Przejdź do głównej zawartości

Twój pierwszy zasób BS19

Ten poradnik buduje mały zasób od zera: komendę /checkin, która daje ocalałemu butelkę wody, najwyżej raz na godzinę. Zajmuje to około 15 minut. Potrzebujesz działającego serwera BS19, dostępu do jego plików i konsoli txAdmin oraz edytora tekstu (VS Code sprawdza się dobrze).

Gdy zadziała, Pisanie zasobu na bazie bs_core pokazuje kolejne kroki: kod klienta, callbacki i pułapki, których warto unikać.

W folderze resources serwera utwórz folder [local] (nawiasy kwadratowe są ważne, robią z niego kategorię, a nie zasób), a w nim folder bs_checkin. Trzymaj własne zasoby w [local], wtedy aktualizacje frameworka nigdy ich nie nadpiszą.

resources/[local]/bs_checkin/
├── fxmanifest.lua
├── config.lua
└── server.lua

Nazwa folderu to nazwa zasobu. Zacznij ją od bs_, żeby nie kolidowała z innym skryptem.

Każdy zasób FiveM potrzebuje tego pliku. Mówi serwerowi, które pliki załadować i po której stronie.

fx_version 'cerulean'
game 'gta5'
lua54 'yes'
name 'bs_checkin'
description 'My first BS19 resource'
shared_scripts {
'@bs_core/shared/sh_bridge.lua', -- gives you BSB (commands, callbacks)
'config.lua',
}
server_scripts { 'server.lua' }
dependencies { 'bs_core', 'bs_inventory' }

Linia @bs_core/shared/sh_bridge.lua ładuje most BS19 do twojego zasobu. Bez niej BSB nie istnieje i plik serwera się wysypie.

Umieść w jednej tabeli każdą wartość, którą właściciel serwera może chcieć zmienić, żeby nikt nie musiał ruszać twojego kodu.

Checkin = {
item = 'water_bottle', -- any item name from bs_inventory's item list
amount = 1,
cooldown = 3600, -- seconds between two check-ins (1 hour)
}
local lastCheckin = {} -- [charId] = os.time() of the last check-in
local function notify(src, kind, message)
TriggerClientEvent('bs:ui:notify', src, { type = kind, message = message })
end
BSB.RegisterCommand('checkin', nil, 'Daily survivor check-in', {}, function(src)
if src == 0 then return print('Run /checkin in game, not in the console.') end
local p = exports.bs_core:GetPlayerSummary(src)
if not p then return notify(src, 'error', 'Pick a character first.') end
local now = os.time()
local last = lastCheckin[p.charId]
if last and now - last < Checkin.cooldown then
local minutes = math.ceil((Checkin.cooldown - (now - last)) / 60)
return notify(src, 'error', ('Come back in %d min.'):format(minutes))
end
local ok, reason = exports.bs_inventory:GiveItem(src, Checkin.item, Checkin.amount)
if not ok then return notify(src, 'error', 'No room: ' .. tostring(reason)) end
lastCheckin[p.charId] = now
notify(src, 'success', ('Welcome back, %s. Here is some water.'):format(p.firstName))
end)

Co robi kod, linia po linii:

  • BSB.RegisterCommand tworzy komendę czatu. nil oznacza, że każdy może jej używać; wpisz tam ACE, np. 'bs.admin', żeby ograniczyć ją do administracji.
  • GetPlayerSummary zwraca nil, dopóki gracz jest na ekranie postaci, więc sprawdź to na początku.
  • Czas odnowienia jest zapisywany na postać (charId), nie na gracza, więc druga postać ma własny check-in. Resetuje się przy restarcie zasobu, co na pierwszy zasób wystarczy.
  • Przedmioty zawsze przechodzą przez exports.bs_inventory:GiveItem. Gdy ekwipunek jest pełny, zwraca false i powód. Nigdy nie zapisuj sam do bazy danych.

Dodaj tę linię na końcu server.cfg, po zasobach BS19:

ensure bs_checkin

Następnie w konsoli na żywo txAdmin (restart serwera nie jest potrzebny):

refresh
ensure bs_checkin

refresh sprawia, że serwer widzi nowy folder. Konsola powinna wypisać Started resource bs_checkin. Gdy później zmienisz plik, samo ensure bs_checkin go przeładuje.

  1. Wejdź na serwer i wybierz postać.
  2. Naciśnij T, wpisz /checkin i naciśnij Enter. Dostajesz zielone powiadomienie i butelkę wody w ekwipunku (I).
  3. Wpisz /checkin jeszcze raz. Dostajesz czerwony komunikat “Come back in 60 min.”.
Co widziszDlaczegoRozwiązanie
Couldn't find resource bs_checkinSerwer nie zauważył folderu albo nazwa się różniUruchom refresh, sprawdź, czy folder nazywa się dokładnie bs_checkin
attempt to index a nil value (global 'BSB')Brakuje linii mostuSprawdź linię @bs_core/shared/sh_bridge.lua w fxmanifest.lua
No such export GetPlayerSummarybs_core jeszcze nie wystartowałTrzymaj ensure bs_checkin pod zasobami BS19 w server.cfg
/checkin nic nie robi, brak błęduJesteś jeszcze na ekranie postaci albo komenda nie została zarejestrowanaWybierz postać, potem poszukaj czerwonej linii [bs_checkin] w konsoli
“No room: …”Ekwipunek jest pełny lub za ciężkiWyrzuć coś i spróbuj ponownie

Każdy czerwony błąd w konsoli podaje też plik i linię. Popraw go, uruchom ponownie ensure bs_checkin i spróbuj jeszcze raz.

  • Zmień item na bandage w config.lua i uruchom ensure bs_checkin. Bez zmiany kodu.
  • Daj też trochę gotówki: exports.bs_core:AddMoney(src, 'cash', 25, 'checkin').
  • Daj XP: exports.bs_core:AddXP(src, 10, 'checkin').
  • Przejrzyj dostępne wywołania w Przegląd exportów i eventów.