Integracja

Integracja

Podłącz swój serwer FiveM ESX do panelu w kilka minut.

Status API

Online

Ostatnia synchronizacja

Brak danych

Gracze w bazie

0 (ostatnie 5)

Gotowa paczka skryptu v1.2.2

Pobierz gotowy folder zenith_sync do wklejenia na swój serwer.

Pobierz ZIP
Kod do wklejenia
-- ZENITH ESX INTEGRATION v1.2.2
-- Skrypt synchronizujący dane z bazy ESX do panelu WWW
-- Optymalizacja: Pełny skan tylko na starcie, później tylko zmiany (Event-based)
-- v1.2.2: Pełna synchronizacja na bieżąco (Ekwipunek, Bronie, Statystyki, Online/Offline)

local API_URL = "https://controlrp.jasiu-dev.pl/api/public/sync"
local SCRIPT_VERSION = "1.2.2"

local DEBUG = true

local function GetESX()
    local obj = nil
    local try = 0
    while obj == nil and try < 3 do
        TriggerEvent('esx:getSharedObject', function(o) obj = o end)
        if obj == nil then
            pcall(function() obj = exports['es_extended']:getSharedObject() end)
        end
        if obj == nil then
            Citizen.Wait(1000)
            try = try + 1
        end
    end
    return obj
end

-- Funkcja do sprawdzania komunikacji z API
local function CheckConnection()
    if DEBUG then print('^3[ZENITH v' .. SCRIPT_VERSION .. '] Sprawdzanie połączenia z API...^7') end
    
    local testData = { test_connection = true, version = SCRIPT_VERSION }
    
    PerformHttpRequest(API_URL, function(err, text, headers)
        if err == 200 then
            print('^2[ZENITH v' .. SCRIPT_VERSION .. '] Połączenie z API działa poprawnie!^7')
            if DEBUG then print('^5[ZENITH DEBUG] Odpowiedź API: ' .. tostring(text) .. '^7') end
        else
            print('^1[ZENITH v' .. SCRIPT_VERSION .. '] BŁĄD KOMUNIKACJI! Status: ' .. tostring(err) .. '^7')
            print('^1[ZENITH v' .. SCRIPT_VERSION .. '] Szczegóły: ' .. tostring(text) .. '^7')
            print('^3[ZENITH v' .. SCRIPT_VERSION .. '] Upewnij się, że Twoja strona jest opublikowana i link API jest poprawny.^7')
        end
    end, 'POST', json.encode(testData), { ['Content-Type'] = 'application/json' })
end

local ESX = nil

local function ExportPlayerData()
    if not ESX then ESX = GetESX() end
    if not ESX then 
        if DEBUG then print('^1[ZENITH v' .. SCRIPT_VERSION .. '] Nie znaleziono obiektu ESX!^7') end
        return 
    end

    if DEBUG then print('^3[ZENITH v' .. SCRIPT_VERSION .. '] Pobieranie danych z bazy danych...^7') end

    local MySQLQuery = nil
    
    if exports['oxmysql'] then
        MySQLQuery = function(query, params, cb)
            exports['oxmysql']:execute(query, params, cb)
        end
    elseif _G.MySQL then
        if MySQL.Async and MySQL.Async.fetchAll then
            MySQLQuery = MySQL.Async.fetchAll
        elseif MySQL.fetchAll then
            MySQLQuery = MySQL.fetchAll
        end
    end

    if not MySQLQuery then
        if DEBUG then print('^1[ZENITH v' .. SCRIPT_VERSION .. '] Nie znaleziono kompatybilnej biblioteki MySQL (mysql-async lub oxmysql)!^7') end
        return
    end

    MySQLQuery('SELECT * FROM users', {}, function(results)
        if not results then 
            if DEBUG then print('^1[ZENITH v' .. SCRIPT_VERSION .. '] Błąd zapytania do bazy lub brak wyników.^7') end
            return 
        end
        
        if #results == 0 then 
            if DEBUG then print('^3[ZENITH v' .. SCRIPT_VERSION .. '] Brak graczy w bazie danych.^7') end
            return 
        end

        local data = {}
        local onlinePlayers = ESX.GetExtendedPlayers()
        local onlineMap = {}
        for _, xPlayer in pairs(onlinePlayers) do onlineMap[xPlayer.identifier] = xPlayer end

        if DEBUG then print('^5[ZENITH DEBUG] Przetwarzanie ' .. #results .. ' graczy z bazy...^7') end

        for i=1, #results do
            local row = results[i]
            local identifier = row.identifier
            local xPlayer = onlineMap[identifier]
            
            local function SafeDecode(val)
                if not val or val == "" then return nil end
                local success, decoded = pcall(json.decode, val)
                if not success and DEBUG then 
                    if val ~= "[]" and val ~= "{}" then
                        print('^1[ZENITH DEBUG] Błąd JSON dla ' .. identifier .. ' w polu: ' .. tostring(val) .. '^7') 
                    end
                end
                return success and decoded or nil
            end

            local playerEntry = {
                identifier = identifier,
                name = (row.firstname or "Gracz") .. " " .. (row.lastname or ""),
                firstname = row.firstname,
                lastname = row.lastname,
                money = row.money or 0,
                bank = row.bank or 0,
                job = row.job or 'unemployed',
                job_grade = row.job_grade or 0,
                group = row.group or 'user',
                health = row.health or 200,
                armour = row.armour or 0,
                inventory = SafeDecode(row.inventory),
                accounts = SafeDecode(row.accounts),
                position = SafeDecode(row.position) or SafeDecode(row.lastpos),
                uid = row.uid,
                digit = row.digit,
                sex = row.sex,
                height = row.height,
                phone_number = row.phone_number,
                skin = SafeDecode(row.skin),
                job_level = row.job_level,
                loadout = SafeDecode(row.loadout),
                lastpos = row.lastpos
            }

            if xPlayer then
                playerEntry.money = 0
                playerEntry.bank = 0
                
                local accounts = xPlayer.getAccounts()
                if accounts then
                    playerEntry.accounts = accounts
                    for _, acc in pairs(accounts) do
                        if acc.name == 'money' or acc.name == 'cash' then
                            playerEntry.money = acc.money or acc.amount or 0
                        elseif acc.name == 'bank' then
                            playerEntry.bank = acc.money or acc.amount or 0
                        end
                    end
                end
                
                playerEntry.inventory = xPlayer.getInventory()
                playerEntry.position = xPlayer.getCoords(true)
                local ped = GetPlayerPed(xPlayer.source)
                if ped and ped ~= 0 then
                    playerEntry.health = GetEntityHealth(ped)
                    playerEntry.armour = GetPedArmour(ped)
                end
            else
                -- Jeśli offline, spróbuj wyciągnąć money/bank z kolumn lub JSONa 'accounts'
                if playerEntry.accounts and type(playerEntry.accounts) == "table" then
                    for k, acc in pairs(playerEntry.accounts) do
                        if type(acc) == "table" then
                            local name = acc.name or acc.label or k
                            local val = acc.money or acc.amount or 0
                            if name == 'money' or name == 'cash' then
                                playerEntry.money = val
                            elseif name == 'bank' then
                                playerEntry.bank = val
                            end
                        elseif type(acc) == "number" then
                            -- Obsługa formatu {"bank":1250,"money":550}
                            if k == 'money' or k == 'cash' then
                                playerEntry.money = acc
                            elseif k == 'bank' then
                                playerEntry.bank = acc
                            end
                        end
                    end
                end
            end
            table.insert(data, playerEntry)
        end

        if DEBUG then print('^2[ZENITH v' .. SCRIPT_VERSION .. '] Wysyłanie danych do ' .. API_URL .. ' (Graczy: ' .. #data .. ')^7') end

        PerformHttpRequest(API_URL, function(err, text)
            if err == 200 then
                if DEBUG then print('^2[ZENITH v' .. SCRIPT_VERSION .. '] Synchronizacja zakończona sukcesem!^7') end
                
                -- Procesowanie ewentualnych zmian zwrotnych (WWW -> Gra)
                local success, response = pcall(json.decode, text)
                if success and response and response.updates then
                    for identifier, updates in pairs(response.updates) do
                        if DEBUG then print('^3[ZENITH] Aktualizowanie gracza: ' .. identifier .. '^7') end
                        
                        -- 1. Aktualizuj w bazie danych (MySQL)
                        local updateQuery = "UPDATE users SET "
                        local params = {}
                        local sets = {}
                        
                        for k, v in pairs(updates) do
                            table.insert(sets, k .. " = @" .. k)
                            params[k] = v
                        end
                        
                        updateQuery = updateQuery .. table.concat(sets, ", ") .. " WHERE identifier = @identifier"
                        params.identifier = identifier
                        
                        MySQLQuery(updateQuery, params, function()
                            if DEBUG then print('^2[ZENITH] Baza danych zaktualizowana dla: ' .. identifier .. '^7') end
                        end)
                        
                        -- 2. Jeśli gracz jest online, aktualizuj xPlayer
                        local xPlayer = onlineMap[identifier]
                        if xPlayer then
                            if updates.money then xPlayer.setMoney(updates.money) end
                            if updates.bank then xPlayer.setAccountMoney('bank', updates.bank) end
                            if updates.job then xPlayer.setJob(updates.job, updates.job_grade or 0) end
                            if updates.group then xPlayer.setGroup(updates.group) end
                        end
                    end
                end
            else
                print('^1[ZENITH v' .. SCRIPT_VERSION .. '] BŁĄD SYNCHRONIZACJI! Status: ' .. tostring(err) .. '^7')
                print('^1[ZENITH v' .. SCRIPT_VERSION .. '] Odpowiedź API: ' .. tostring(text) .. '^7')
            end
        end, 'POST', json.encode(data), { ['Content-Type'] = 'application/json' })
    end)
end

Citizen.CreateThread(function()
    Citizen.Wait(5000)
    print('^2[ZENITH v' .. SCRIPT_VERSION .. '] Integration started.^7')
    while true do
        ExportPlayerData()
        Citizen.Wait(300000)
    end
end)
Specyfikacja API
Endpointhttps://controlrp.jasiu-dev.pl/api/public/sync
Method
POST
Wersja
1.2.2
Logi Integracji
[SYSTEM] Monitoring aktywny...
[SERVER] Time: 1:09:53 AM
[SYNC] Oczekiwanie na pierwsze dane...
Autentykacja poprawna
Baza danych połączona
SSL Szyfrowanie aktywne
Wymagania
  • •FiveM Server build 5000+
  • •ESX Framework (Legacy/1.2+)
  • •Dostęp do Internetu