From b92e26129f7ae4dceb88214169e411bfba7dd206 Mon Sep 17 00:00:00 2001 From: Jim Shield Date: Thu, 22 May 2025 14:10:30 +0100 Subject: [PATCH] Convert to globalstatebag syncing for optimization When consumables are added from outside the script, it uses global statebags to ensure data is received successfully. This syncs live and for players who have just connected This removes the callbacks in the script to help optimization --- client/client.lua | 76 ++++++++++++++++++++++++++++++----------------- server/server.lua | 30 +++++++++---------- 2 files changed, 62 insertions(+), 44 deletions(-) diff --git a/client/client.lua b/client/client.lua index e0a5964..b8be995 100644 --- a/client/client.lua +++ b/client/client.lua @@ -1,37 +1,57 @@ local alcoholCount, drugCount, consuming, cancelled = 0, 0, false, false Consumables, Emotes = {}, {} -local function syncConsumables() - Consumables = triggerCallback(getScript()..":server:syncConsumables") - Emotes = triggerCallback(getScript()..":server:syncEmotes") - debugPrint("^5Debug^7: ^2Retrieved ^6"..countTable(Consumables).." ^2Items and ^6"..countTable(Emotes).." ^2Emotes^7") -end - -RegisterNetEvent(getScript()..":client:syncConsumables", function(NewConsumables) - if debugMode then - for k, v in pairs(NewConsumables) do - if not Consumables[k] then - print("^5Debug^7: ^2New Item Info added^7: ^6"..k.."^7") - end - end - end - Consumables = NewConsumables -end) -RegisterNetEvent(getScript()..":client:syncEmotes", function(NewEmotes) - if debugMode then - for k, v in pairs(NewEmotes) do - if not Emotes[k] then - print("^5Debug^7: ^2New Emote Info added^7: ^6"..k.."^7") - end - end - end - Emotes = NewEmotes -end) - onPlayerLoaded(function() - syncConsumables() + -- Wait until statebag exists, then trigger local handler + CreateThread(function() + while not GlobalState.jimConsumableItems do Wait(100) end + local newConsumables = GlobalState.jimConsumableItems + for k in pairsByKeys(newConsumables) do + if not Consumables[k] then + debugPrint("^5Statebag^7: ^2New ^3Consumable ^2Info synced^7: ^6"..k.."^7") + end + end + while not GlobalState.jimConsumableEmotes do Wait(100) end + local newEmotes = GlobalState.jimConsumableEmotes + for k in pairsByKeys(newEmotes) do + if not Emotes[k] then + debugPrint("^5Statebag^7: ^2New ^3Emote ^2Info synced^7: ^6"..k.."^7") + end + end + Consumables = newConsumables + Emotes = newEmotes + debugPrint("^5Statebag^7: ^2Synced ^6"..countTable(Consumables).." ^2Items and ^6"..countTable(Emotes).." ^2Emotes^7") + end) end, true) +-- Handlers to recieve global statebag data from the server +AddStateBagChangeHandler("jimConsumableItems", nil, function(bagName, key, value, _unused) + if type(value) == "table" then + local newItemCount = 0 + for k in pairsByKeys(value) do + if not Consumables[k] then + newItemCount += 1 + debugPrint("^5Statebag^7: ^2New ^3Consumable ^2Info synced^7: ^6"..k.."^7") + end + end + Consumables = value + debugPrint("^5Statebag^7: ^2Synced ^6"..newItemCount.." ^2new Consumables^7") + end +end) +AddStateBagChangeHandler("jimConsumableEmotes", nil, function(bagName, key, value, _unused) + if type(value) == "table" then + local newEmoteCount = 0 + for k in pairsByKeys(value) do + if not Emotes[k] then + newEmoteCount += 1 + debugPrint("^5Statebag^7: ^2New ^3Emote ^2Info synced^7: ^6"..k.."^7") + end + end + Emotes = value + debugPrint("^5Statebag^7: ^2Synced ^6"..newEmoteCount.." ^2new Emotes^7") + end +end) + RegisterNetEvent(getScript()..':Consume', function(itemName) if not Consumables[itemName] then return end local consumable = Consumables[itemName] diff --git a/server/server.lua b/server/server.lua index 36b1636..d09d6d0 100644 --- a/server/server.lua +++ b/server/server.lua @@ -9,11 +9,15 @@ onResourceStart(function() end --Export Import System-- - createCallback(getScript()..':server:syncConsumables', function(source) return Consumables end) - createCallback(getScript()..':server:syncEmotes', function(source) return Emotes end) - + GlobalState.jimConsumableItems = Consumables + GlobalState.jimConsumableEmotes = Emotes end, true) +onResourceStop(function() + GlobalState.jimConsumableItems = Consumables + GlobalState.jimConsumableEmotes = Emotes +end) + RegisterNetEvent(getScript()..':server:addNeed', function(amount, type) local Player = Core.Functions.GetPlayer(source) if not Player then return end if type == "thirst" then @@ -27,14 +31,15 @@ end) local syncScheduled = false function syncConsumables() - debugPrint("^5Debug^7: ^2Sending ^6"..countTable(Consumables).." ^3Consumables ^2to all clients^7") - TriggerClientEvent(getScript()..":client:syncConsumables", -1, Consumables) + debugPrint("^5Statebag^7: ^2Sending ^6"..countTable(Consumables).." ^3Consumables ^2to all clients^7") + GlobalState.jimConsumableItems = Consumables syncScheduled = false end + local emoteSyncScheduled = false function syncEmotes() - debugPrint("^5Debug^7: ^2Sending ^6"..countTable(Emotes).." ^3Emotes to all clients^7") - TriggerClientEvent(getScript()..":client:syncEmotes", -1, Emotes) + debugPrint("^5Statebag^7: ^2Sending ^6"..countTable(Emotes).." ^3Emotes to all clients^7") + GlobalState.jimConsumableEmotes = Emotes emoteSyncScheduled = false end @@ -45,7 +50,7 @@ RegisterNetEvent(getScript()..':server:syncAddItem', function(itemName, data) debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Item^7: '"..itemName.."'") if not syncScheduled then syncScheduled = true - Citizen.SetTimeout(5000, syncConsumables) + SetTimeout(5000, syncConsumables) end else debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Item^7: '"..itemName.."'") @@ -58,20 +63,13 @@ RegisterNetEvent(getScript()..':server:syncAddEmote', function(emoteName, data) debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Emote^7: '"..emoteName.."'") if not emoteSyncScheduled then emoteSyncScheduled = true - Citizen.SetTimeout(5000, syncEmotes) + SetTimeout(5000, syncEmotes) end else debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Emote^7: '"..emoteName.."'") end end) -RegisterNetEvent(getScript()..":server:syncConsumables", function() - TriggerClientEvent(getScript()..':client:syncConsumables', -1, Consumables) -end) -RegisterNetEvent(getScript()..":server:syncEmotes", function() - TriggerClientEvent(getScript()..':client:syncEmotes', -1, Emotes) - -end) --[[ Core.Commands.Add('consumableCreator', "Create consumables (admin only)", {}, false, function(source) if source > 0 then return TriggerClientEvent(getScript()..":client:consumableCreator", source) end