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
This commit is contained in:
Jim Shield
2025-05-22 14:10:30 +01:00
parent 129b65deda
commit b92e26129f
2 changed files with 62 additions and 44 deletions

View File

@@ -1,37 +1,57 @@
local alcoholCount, drugCount, consuming, cancelled = 0, 0, false, false local alcoholCount, drugCount, consuming, cancelled = 0, 0, false, false
Consumables, Emotes = {}, {} 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() 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) 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) RegisterNetEvent(getScript()..':Consume', function(itemName)
if not Consumables[itemName] then return end if not Consumables[itemName] then return end
local consumable = Consumables[itemName] local consumable = Consumables[itemName]

View File

@@ -9,11 +9,15 @@ onResourceStart(function()
end end
--Export Import System-- --Export Import System--
createCallback(getScript()..':server:syncConsumables', function(source) return Consumables end) GlobalState.jimConsumableItems = Consumables
createCallback(getScript()..':server:syncEmotes', function(source) return Emotes end) GlobalState.jimConsumableEmotes = Emotes
end, true) end, true)
onResourceStop(function()
GlobalState.jimConsumableItems = Consumables
GlobalState.jimConsumableEmotes = Emotes
end)
RegisterNetEvent(getScript()..':server:addNeed', function(amount, type) RegisterNetEvent(getScript()..':server:addNeed', function(amount, type)
local Player = Core.Functions.GetPlayer(source) if not Player then return end local Player = Core.Functions.GetPlayer(source) if not Player then return end
if type == "thirst" then if type == "thirst" then
@@ -27,14 +31,15 @@ end)
local syncScheduled = false local syncScheduled = false
function syncConsumables() function syncConsumables()
debugPrint("^5Debug^7: ^2Sending ^6"..countTable(Consumables).." ^3Consumables ^2to all clients^7") debugPrint("^5Statebag^7: ^2Sending ^6"..countTable(Consumables).." ^3Consumables ^2to all clients^7")
TriggerClientEvent(getScript()..":client:syncConsumables", -1, Consumables) GlobalState.jimConsumableItems = Consumables
syncScheduled = false syncScheduled = false
end end
local emoteSyncScheduled = false local emoteSyncScheduled = false
function syncEmotes() function syncEmotes()
debugPrint("^5Debug^7: ^2Sending ^6"..countTable(Emotes).." ^3Emotes to all clients^7") debugPrint("^5Statebag^7: ^2Sending ^6"..countTable(Emotes).." ^3Emotes to all clients^7")
TriggerClientEvent(getScript()..":client:syncEmotes", -1, Emotes) GlobalState.jimConsumableEmotes = Emotes
emoteSyncScheduled = false emoteSyncScheduled = false
end end
@@ -45,7 +50,7 @@ RegisterNetEvent(getScript()..':server:syncAddItem', function(itemName, data)
debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Item^7: '"..itemName.."'") debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Item^7: '"..itemName.."'")
if not syncScheduled then if not syncScheduled then
syncScheduled = true syncScheduled = true
Citizen.SetTimeout(5000, syncConsumables) SetTimeout(5000, syncConsumables)
end end
else else
debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Item^7: '"..itemName.."'") 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.."'") debugPrint("^5Debug^7: "..GetInvokingResource().." ^2is sending new ^3Emote^7: '"..emoteName.."'")
if not emoteSyncScheduled then if not emoteSyncScheduled then
emoteSyncScheduled = true emoteSyncScheduled = true
Citizen.SetTimeout(5000, syncEmotes) SetTimeout(5000, syncEmotes)
end end
else else
debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Emote^7: '"..emoteName.."'") debugPrint("^1Debug^7: "..GetInvokingResource().." ^2is sending ^1duplicate ^3Emote^7: '"..emoteName.."'")
end end
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) Core.Commands.Add('consumableCreator', "Create consumables (admin only)", {}, false, function(source)
if source > 0 then return TriggerClientEvent(getScript()..":client:consumableCreator", source) end if source > 0 then return TriggerClientEvent(getScript()..":client:consumableCreator", source) end