-- SoulShive Network v3.1 — resource FiveM COMPLET -- SDK oficial SoulShive — la paritate cu pluginul CS 1.6 v3.1. -- Redirect STRICT per-jucător (nu mai mută pe toată lumea) + cache local (fallback). local API_KEY = "c9afd676173cbb158d7a8e9bd5e74c11a7beffac1a4c1a026b492de856261cc0" local BASE_URL = "https://soulshive.com" local HEARTBEAT_MS = 60000 local FULL_CHECK_MS = 10000 local FULL_NOTIFY_COOLDOWN_MS = 60000 local lastFullNotify = 0 local cacheIp, cachePort = nil, nil local function loadCache() local ok, data = pcall(LoadResourceFile, GetCurrentResourceName(), 'soulshive_cache.json') if ok and data then local d = json.decode(data) if d then cacheIp, cachePort = d.ip, d.port end end end local function saveCache(ip, port) cacheIp, cachePort = ip, port SaveResourceFile(GetCurrentResourceName(), 'soulshive_cache.json', json.encode({ ip = ip, port = port }), -1) end local function apiPost(path, payload, cb) PerformHttpRequest(BASE_URL .. path, function(code, data) if cb then cb(code, data) end end, 'POST', json.encode(payload), { ['Content-Type'] = 'application/json' }) end local function apiGet(path, cb) PerformHttpRequest(BASE_URL .. path .. "?api_key=" .. API_KEY, function(code, data) if cb then cb(code, data) end end, 'GET') end -- ── HEARTBEAT ── local function sendHeartbeat() local players = GetNumPlayerIndices() local maxPlayers = GetConvarInt("sv_maxclients", 32) local hostname = GetConvar("sv_hostname", "FiveM Server") apiPost("/api/v1/heartbeat.php", { api_key = API_KEY, hostname = hostname, map = GetCurrentResourceName(), players = players, max_players = maxPlayers, version = "3.1" }, function(code, data) if code ~= 200 then print(("[SoulShive Network] heartbeat eșuat (cod %s)"):format(code)); return end local ok, resp = pcall(json.decode, data) if ok and resp and resp.update then print("[SoulShive Network] Actualizare disponibilă — vezi soulshive.com/apps.php") end end) end -- ── SERVER PLIN: doar anunț global, fără mutare forțată ── local function checkFullAndNotify() local players = GetNumPlayerIndices() local maxPlayers = GetConvarInt("sv_maxclients", 32) if players < maxPlayers then return end if (GetGameTimer() - lastFullNotify) < FULL_NOTIFY_COOLDOWN_MS then return end lastFullNotify = GetGameTimer() for _, playerId in ipairs(GetPlayers()) do TriggerClientEvent('chat:addMessage', playerId, { args = { "^3[SoulShive]", "Serverul e plin — scrie /next pentru un server liber." } }) end end -- ── /next — redirect STRICT pentru jucătorul care a scris comanda ── RegisterCommand('next', function(source) if source == 0 then return end apiGet("/api/v1/redirect.php", function(code, data) if code ~= 200 then if cacheIp then TriggerClientEvent('chat:addMessage', source, { args = { "^3[SoulShive]", "API indisponibil — ultimul server cunoscut: " .. cacheIp .. ":" .. cachePort } }) TriggerClientEvent('soulshive:executeRedirect', source, cacheIp, cachePort) else TriggerClientEvent('chat:addMessage', source, { args = { "^1[SoulShive]", "Niciun server disponibil momentan." } }) end return end local ok, resp = pcall(json.decode, data) if not (ok and resp and resp.redirect) then TriggerClientEvent('chat:addMessage', source, { args = { "^1[SoulShive]", "Niciun server liber momentan." } }) return end saveCache(resp.ip, resp.port) TriggerClientEvent('chat:addMessage', source, { args = { "^2[SoulShive]", "Te conectăm la " .. resp.ip .. ":" .. resp.port .. "..." } }) TriggerClientEvent('soulshive:executeRedirect', source, resp.ip, resp.port) apiPost("/api/v1/logs.php", { api_key = API_KEY, event = "redirect_executed", message = resp.ip .. ":" .. resp.port }) end) end, false) -- ── conectare / deconectare jucători ── AddEventHandler('playerConnecting', function(name, setKickReason, deferrals) local src = source Wait(0) local identifiers = GetPlayerIdentifiers(src) local steamid = "unknown" for _, id in ipairs(identifiers) do if id:find("steam:") then steamid = id end end apiPost("/api/v1/player/connect.php", { api_key = API_KEY, steamid = steamid, name = name }) end) AddEventHandler('playerDropped', function(reason) local src = source local identifiers = GetPlayerIdentifiers(src) local steamid = "unknown" for _, id in ipairs(identifiers) do if id:find("steam:") then steamid = id end end apiPost("/api/v1/player/disconnect.php", { api_key = API_KEY, steamid = steamid }) end) -- ── /servers — statistici live din rețea ── RegisterCommand('servers', function(source) apiGet("/api/v1/stats.php", function(code, data) if code == 200 then if source == 0 then print(data) else TriggerClientEvent('chat:addMessage', source, { args = { "^5[SoulShive]", data } }) end end end) end, false) -- ── comenzi admin (consolă server) ── RegisterCommand('soulshive_status', function(source) if source ~= 0 then return end print(("[SoulShive] Status: cache=%s"):format(cacheIp and (cacheIp .. ":" .. cachePort) or "gol")) end, true) CreateThread(function() loadCache() Wait(5000) while true do sendHeartbeat(); Wait(HEARTBEAT_MS) end end) CreateThread(function() while true do Wait(FULL_CHECK_MS); checkFullAndNotify() end end) print("[SoulShive Network] v3.1 pornit — SDK oficial SoulShive, raportare + redirect per-jucător")