Jak oceniać, testować i utrzymywać FiveM Scripts

How to Evaluate and Test FiveM Scripts Before You Buy

Before you buy or install a FiveM script, test it like a QA lead: run it in an isolated Docker “Test City”, work through the acceptance checklist, score the risk from 0-100, and vet the vendor before money changes hands. This guide gives server owners and developers the full workflow — a copy-paste FXServer + MariaDB docker compose stack, resmon performance limits, security checks, and a maintenance playbook for after you ship.

TL;DR

  • Uruchom Test City (Docker) aby bezpiecznie izolować i testować wydajność dowolnego skryptu.
  • Uruchom Lista kontrolna akceptacji zanim zmieni właściciela choćby grosz.
  • Użyj Wskaźnik ryzyka (0–100) aby zdecydować: wysłać/wstrzymać/odrzucić.
  • Sprawdź sprzedawców za pomocą Rubryka Sprzedawcy (nie pomijaj tego).
  • Jeśli kupujesz, wybieraj renomowane sklepy — zobacz nasze rekomendacje: Najlepsze sklepy Tebex.

Część 1 — “Test City” (Docker) do bezpiecznej i powtarzalnej kontroli jakości skryptów

Co otrzymujesz

  • Konteneryzowany FXServer + MariaDB (+ Adminer)
  • Czyste server.cfg z oxmysql i podstawowe zasoby
  • Zamontowane przez bind mount resources/custom gdzie umieszczasz testowany skrypt
  • Deterministyczne nazwy sieci/porty dla prostych ciągów DB

Pobierz test-city.zip (Github)

Jak używać:

  1. Rozpakuj → cd test-city
  2. Kopiuj .env.example do .env i ustaw swoje LICENSE_KEY (i dane do bazy danych, jeśli chcesz).
  3. Wrzuć oxmysql do server-data/resources/[standalone]/oxmysql/.
  4. Umieść testowany skrypt w server-data/resources/custom/<scriptname>/ i dodaj ensure <scriptname> do server.cfg.
  5. docker compose build && docker compose up -d → połącz przez Direct Connect z localhost:30120.

Wymagania wstępne: Docker + Docker Compose, klucz licencyjny cfx oraz oxmysql kopię zasobu (wrzuć do server-data/resources/[standalone]/oxmysql).

Układ folderów

test-city/
├─ docker-compose.yml
├─ fxserver/
│ ├─ Dockerfile
│ └─ entrypoint.sh
├─ server-data/
│ ├─ server.cfg
│ └─ resources/
│ ├─ [standalone]/oxmysql/ # place oxmysql here
│ └─ custom/ # put the script under test here (e.g., myscript/)
└─ .env

.env (przykład)

LICENSE_KEY=changeme_cfx_license_key
MYSQL_DATABASE=fivem
MYSQL_USER=fivem
MYSQL_PASSWORD=fivempw
MYSQL_ROOT_PASSWORD=rootpw
FX_ARTIFACT_URL=https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/LATEST.tar.xz
# Tip: replace with a specific artifact URL you trust for reproducibility.

docker-compose.yml

version: "3.9"

networks:
 testcity:

volumes:
 db_data:

services:
 db:
 image: mariadb:10.11
 restart: unless-stopped
 environment:
 MYSQL_DATABASE: ${MYSQL_DATABASE}
 MYSQL_USER: ${MYSQL_USER}
 MYSQL_PASSWORD: ${MYSQL_PASSWORD}
 MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
 command: >
 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
 --innodb_buffer_pool_size=256M
 volumes:
 - db_data:/var/lib/mysql
 networks: [testcity]

 adminer:
 image: adminer:4
 restart: unless-stopped
 ports:
 - "8080:8080"
 networks: [testcity]
 depends_on: [db]

 fxserver:
 build:
 context: ./fxserver
 args:
 FX_ARTIFACT_URL: ${FX_ARTIFACT_URL}
 restart: unless-stopped
 environment:
 LICENSE_KEY: ${LICENSE_KEY}
 MYSQL_DATABASE: ${MYSQL_DATABASE}
 MYSQL_USER: ${MYSQL_USER}
 MYSQL_PASSWORD: ${MYSQL_PASSWORD}
 depends_on: [db]
 networks: [testcity]
 ports:
 - "30120:30120/udp"
 - "30120:30120/tcp"
 - "40120:40120/tcp" # txAdmin (optional)
 volumes:
 - ./server-data:/opt/fivem/server-data

fxserver/Dockerfile

FROM debian:bookworm-slim

ARG FX_ARTIFACT_URL
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends 
 xz-utils curl ca-certificates tini bash && 
 rm -rf /var/lib/apt/lists/*

# Fetch & extract FXServer artifact (URL provided via build-arg)
RUN mkdir -p /opt/fivem && 
 curl -fsSL "$FX_ARTIFACT_URL" -o /opt/fivem/fx.tar.xz && 
 tar -xJf /opt/fivem/fx.tar.xz -C /opt/fivem && 
 rm -f /opt/fivem/fx.tar.xz

# Non-root
RUN useradd -ms /bin/bash fivem
USER fivem

WORKDIR /opt/fivem
COPY --chown=fivem:fivem ../server-data /opt/fivem/server-data
COPY --chown=fivem:fivem entrypoint.sh /entrypoint.sh

ENTRYPOINT ["/usr/bin/tini","--"]
CMD ["/bin/bash","/entrypoint.sh"]

fxserver/entrypoint.sh

#!/usr/bin/env bash
set -euo pipefail

# Provide DB string for oxmysql via server.cfg (already set there),
# just ensure the DB is reachable before boot to avoid spam errors.
echo "Waiting for database..."
until nc -z db 3306; do sleep 1; done
echo "DB ready."

# Run FXServer with our server.cfg
# Most Linux artifacts ship a run.sh in the artifact root.
exec bash /opt/fivem/run.sh +exec /opt/fivem/server-data/server.cfg

Jeśli twój artefakt używa innej ścieżki uruchamiania, dostosuj ostatnią linię odpowiednio (np., /opt/fivem/alpine/opt/cfx-server/run.sh).

server-data/server.cfg (chudy, gotowy do testów)

# ---------- Identity ----------
sv_licenseKey "%LICENSE_KEY%" # injected by env in entrypoint command or replace manually
sv_hostname "Test City — Script QA"
sets tags "qa,testing,fivemx"
sv_maxclients 2
onesync on
sv_scriptHookAllowed 0
sv_enforceGameBuild 3095

# ---------- Networking ----------
endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"

# ---------- Database (oxmysql) ----------
set mysql_connection_string "mysql://%MYSQL_USER%:%MYSQL_PASSWORD%@db:3306/%MYSQL_DATABASE%?charset=utf8mb4"

# ---------- Core / Base resources ----------
ensure mapmanager
ensure chat
ensure spawnmanager
ensure sessionmanager
ensure hardcap
ensure baseevents

# ---------- Datastore ----------
ensure oxmysql

# ---------- Under test ----------
# Drop your script folder into resources/custom/<scriptname> and enable here:
# ensure myscript

# ---------- QA helpers ----------
# Verbose logging in dev
setr con_minSeverity info

# Enable txAdmin panel (optional)
setr txAdminPort 40120

Włącz swój skrypt: skopiuj go do server-data/resources/custom/myscript/ i dodaj ensure myscript do dolnego bloku.

Uruchom to

cd test-city
docker compose build
docker compose up -d
# Adminer at http://localhost:8080 (server: db, user: fivem, pass: fivempw)
# Connect FiveM client → Direct Connect: your-docker-host:30120

Część 2 — Lista kontrolna akceptacji skryptu (Nie pomijaj)

Używaj tego za każdym razem. Skopiuj do swojego trackera i odznaczaj elementy.

A. Kontrola wstępna (przed instalacją)

  • Typ źródła: Otwarte źródło \/ częściowo otwarte \/ tylko escrow.
  • Wymienione zależności: framework (ESX\/QBCore\/QBOX), ox_lib, oxmysql, PolyZone, itp.
  • fxmanifest.lua: lua54 'yes', poprawny game 'gta5', fx_version nie przestarzały.
  • Dokumentacja: kroki instalacji, przykłady konfiguracji, uprawnienia, lokalizacje, znane konflikty.
  • Licencja/Regulamin: prawa użytkowania, polityka zwrotów, aktualizacje, kanał wsparcia.

B. Instalowalność

  • Brak błędów konsoli przy ensure: zero śladów stosu lub spam o brakujących zasobach.
  • Brak deprecated natives spamu.
  • Konfiguracja ładuje się czysto: brak błędów składni JSON/Lua.
  • Migracje bazy danych: tworzenie tabel raz; ponowne uruchomienia nie stosują ponownie ani nie psują.

C. Funkcjonalność

  • Rdzeń przepływy działają: przetestowana ścieżka szczęśliwa (np. zakup, przepływ pracy, crafting).
  • Przypadki brzegowe: nieprawidłowe dane wejściowe, brakujące uprawnienia, ilości poza zakresem.
  • Lokalizacja: brak zakodowanych na stałe ciągów, jeśli obiecano lokalizacje.
  • Uprawnienia: komendy dla personelu/admina zabezpieczone; brak swobodnego dostępu po stronie klienta.

D. Wydajność (klient i serwer)

E. Bezpieczeństwo

  • Walidacja po stronie serwera: każde zdarzenie serwera jest walidowane source, uprawnienia i typy wejścia.
  • Brak zaufania do klienta: zmiany pieniędzy/inwentarza tylko z logiki serwera.
  • Brak eval/loadstring/kod zdalny wzory.
  • Anty-nadużycia: limity szybkości/throttling na spamerskich punktach końcowych.
  • Integralność szyfrowania: brak ukrytych drzwi w niezaszyfrowanych modułach ładowania konfiguracji.

Dobry wzorzec zdarzeń (przykład):

RegisterNetEvent('myscript:buy', function(item, amount)
 local src = source
 if type(item) ~= 'string' or type(amount) ~= 'number' or amount < 1 then return end
 if not HasPermission(src, 'shop.buy') then return end
 local xPlayer = GetPlayer(src) -- framework adapter
 if not xPlayer then return end
 -- validate price server-side, check inventory limits, do DB in a transaction
end)

F. Kompatybilność i czystość

  • Obecne adaptery frameworków (ESX/QBCore/QBOX) lub jasno zadeklarowane jako nieobsługiwane.
  • Brak wycieku globalnych, unikalne nazwy zdarzeń, brak założeń co do nazwy zasobu.
  • Czysta deinstalacja: usunięcie zasobu nie psuje innych.

Część 3 — Model ilościowej oceny ryzyka (0–100)

Użyj tego do podjęcia decyzji “wysłać/zatrzymać/odrzucić”. Niższy wynik jest lepszy.

CzynnikWagaJak oceniać (0=dobrze → 5=źle)
Wydajność0.20resmon bezczynność: 0=≤0.10ms, 1=≤0.20, 3=≤0.50, 5=>0.50; skoki dodają +1
Bezpieczeństwo0.250=wszystko zweryfikowane przez serwer + limity; 3=niektóre luki; 5=ufność do klienta / niebezpieczne zdarzenia
Stabilność0.150=brak błędów; 3=sporadyczne ostrzeżenia; 5=częste błędy/zacięcia
Zgodność0.100=adaptery/testy; 3=tylko jeden framework; 5=łamie wspólne zależności
Utrzymanie0.100=docs/changelog/wersje semantyczne; 5=brak dokumentacji/porzucone
Łańcuch dostaw/Dostawca0.200=renomowany, historia, zwroty; 5=nieznany, brak polityki

Formuła

RiskScore = 100 * Σ(weight_i * (score_i / 5))

Zespoły i Akcje

  • 0–24 (Niskie): Wyślij do środowiska staging, monitoruj.
  • 25–49 (Umiarkowany): Poprawki wymagane przed uruchomieniem.
  • 50–74 (Wysoki): Przytrzymaj; poproś o poprawki od dostawcy lub wymień.
  • 75–100 (Krytyczne): Odrzuć.

Przykład

  • Wydajność=1, Bezpieczeństwo=3, Stabilność=1, Kompatybilność=1, Utrzymanie=2, Dostawca=1
  • Ryzyko = 100*(.2*.2 + .25*.6 + .15*.2 + .1*.2 + .1*.4 + .2*.2) = 34 → Umiarkowany

Część 4 — Kryteria oceny dostawcy (oceniaj każdy od 0 do 5, im wyżej, tym lepszy)

CriterionJak wygląda “dobrze”Uwagi
Tożsamość i HistoriaWyraźna marka, lata aktywności, spójny uchwytUnikaj tymczasowych sklepów
DokumentacjaInstalacja + konfiguracja + uprawnienia + rozwiązywanie problemówZrzuty ekranu/gify pomagają
Częstotliwość aktualizacjiChangelog, wersje semantyczne, ostatnie commity/wydaniaKwartalnie lub częściej jest w porządku
Jakość wsparciaSLA dla zgłoszeń/Discord, powtarzalne poprawki, nie tylko “restart”Przykładowe odpowiedzi
Przejrzystość problemówZnane problemy publiczne i plan działaniaUczciwość > perfekcja
Wyjaśnienie zwrotów/warunków sprzedażyOkres zwrotu, warunki, warunki licencjiŻadnych ciemnych wzorców
Dowód testowaniaWideo ze środowiska staging, metryki wydajności, lista frameworkówJeszcze lepiej: serwer demonstracyjny
Higiena bezpieczeństwaWspomina o kontrolach po stronie serwera, brak wrażliwych kluczy, brak evalZapytaj o audyty
Polityka zgodnościESX/QBCore/QBOX podano, adaptery, macierz wersjiObsługiwane przez państwo wersje
Ceny i wartośćUczciwe jak na złożoność, bez płatnych zależnościUważaj na pułapki sprzedażowe

Ocena w skali (0–50):

  • 40–50: Silny — preferowany dostawca
  • 30–39: Akceptowalne — monitoruj
  • 20–29: Słaby — postępuj ostrożnie
  • <20: Unikaj

Wskazówka pro: Sprawdź z renomowanymi platformami. Zacznij tutaj: Najlepsze sklepy Tebex.


Część 5 — Podręcznik utrzymania (po wdrożeniu)

  1. Przypinanie wersji: blokuj wydania skryptów + wersje zależności (np., oxmysql, ox_lib).
  2. Najpierw staging: wszystkie aktualizacje trafiają do Test City; uruchom ponownie listę kontrolną akceptacji.
  3. Kopie zapasowe i przywracanie: Kopia zapasowa bazy danych + pliki zasobów przed każdą aktualizacją. Zachowaj Rollback.md z dokładnymi krokami.
  4. Test dymny CI (opcjonalny, zalecany): Połączenie klienta headless + makro poleceń do głównych przepływów; parsowanie konsoli serwera pod kątem błędów.
  5. Metryki operacyjne: prowadź prosty dziennik dla każdego skryptu: średni resmon (bezczynny/aktywny), liczba błędów/sesja, uwagi dotyczące incydentów.
  6. Dyscyplina dziennika zmian: wymagaj dzienników zmian dostawcy; zachowaj własne notatki dotyczące integracji.
  7. Zmniejsz ryzyko zaplanowanych zdarzeń: aktualizuj poza godzinami szczytu; ogłaszaj okna konserwacyjne.

Część 6 — Szablony, które możesz skopiować

A. Plan testów (na skrypt)

# Script Test Plan — <name> <version>

## Context
Framework(s): ESX/QBCore/QBOX
Dependencies: oxmysql vX, ox_lib vY, PolyZone vZ
DB Migrations: yes/no
Escrow: yes/no

## Functional Cases
- [ ] Case 1:
- [ ] Case 2:
- [ ] Negative 1:

## Performance
resmon idle: ____ ms
resmon active: ____ ms (scenario: ______)

## Security Checks
- [ ] All server events validate source/perm/input
- [ ] Rate limits present
- [ ] No client-trusted money/inventory mutations

## Logs & Errors
Paste snippet (server + F8): 

## Result
Pass/Fail + Notes

B. Rollback.md (szkielet)

# Rollback — <date> <script> <from→to>

1) Disable script: `stop <resource>`
2) Restore resource files from backup: <path>
3) Restore DB snapshot: <path/command>
4) Restart FXServer
5) Verify: console clean, perf normal, flows ok

C. Szablon zgłoszenia

**Summary**
What happened vs expected, with timestamps.

**Repro Steps**
1) ...
2) ...

**Env**
Artifact build:
Framework & versions:
Script version:
Other deps:

**Logs**
Server console:
F8:

**Attachments**
Screens/video if possible.

Jak efektywnie korzystać z tego przewodnika

  1. Bootstrap Test City raz, zachowaj czystość.
  2. Dla każdego kandydującego skryptu:
    • Wprowadź resources/custom/, włącz w server.cfg.
    • Uruchom Lista kontrolna akceptacji.
    • Oblicz Wynik ryzyka.
    • Zweryfikuj sprzedawcę za pomocą Rubryka Sprzedawcy.
  3. Jeśli przejdzie, scal z gałęzią staging; jeśli nie, poproś o poprawki lub zrezygnuj.

Potrzebujesz więcej przewodników po testach? Learn how to measure script performance with Resmon in FiveM, fix server thread hitch warnings, and build the Part 1 test server with Docker for FiveM.

After the test workflow is ready, compare the exact framework, dependencies, delivered files and setup notes in the FiveM scripts marketplace.