mirror of
https://github.com/jimathy/jim_bridge.git
synced 2026-08-17 05:56:02 +01:00
Complete refactor of handling of framework info
I've moved the framework caching to a new file `frameworkCache.lua` This now caches the framework data once when `jim_bridge` starts Then in `coreloader.lua` now, the information that is cached is now called from that script This also includes better handling of ESX cached data and should stop errors This greatly optimizes the loading of all my scripts and lowers server load to speed up server start times I have been testing this for just under a week and 6 different test servers and it appears to work fine
This commit is contained in:
@@ -52,7 +52,7 @@ function onPlayerLoaded(func, onStart)
|
||||
onPlayerFramework = ESXExport
|
||||
AddEventHandler('esx:playerLoaded', function()
|
||||
if waitForSharedLoad() then
|
||||
if isStarted(ESXExport) then Wait(11000) end
|
||||
if isStarted(ESXExport) then Wait(1000) end
|
||||
tempFunc()
|
||||
end
|
||||
end
|
||||
@@ -105,12 +105,16 @@ end
|
||||
--- -- Initialization code on resource start.
|
||||
--- end, true)
|
||||
--- ```
|
||||
local hasPrinted = false
|
||||
function onResourceStart(func, thisScript)
|
||||
debugPrint("^6Bridge^7: ^2Registering ^3onResourceStart^7()")
|
||||
AddEventHandler('onResourceStart', function(resourceName)
|
||||
if getScript() == resourceName and (thisScript or true) then
|
||||
if waitForSharedLoad() then
|
||||
debugPrint("^6Bridge^7: ^2Shared Load Detected^7.")
|
||||
if not hasPrinted then
|
||||
debugPrint("^6Bridge^7: ^2Shared Load Detected^7.")
|
||||
hasPrinted = true
|
||||
end
|
||||
if isStarted(ESXExport) then Wait(10000) end
|
||||
func()
|
||||
end
|
||||
@@ -186,22 +190,38 @@ function waitForLogin()
|
||||
end
|
||||
end
|
||||
|
||||
local messageShown = false
|
||||
function waitForSharedLoad()
|
||||
local timeout = 100000 -- 10 seconds in milliseconds
|
||||
local startTime = GetGameTimer()
|
||||
local loaded = true
|
||||
--Wait(1000)
|
||||
local count = {}
|
||||
local loop = 0
|
||||
while ((not Jobs or not next(Jobs)) and (not Items or not next(Items)) and (not Vehicles or not next(Vehicles))) and (GetGameTimer() - startTime) < timeout do
|
||||
print((GetGameTimer() - startTime) < timeout)
|
||||
if not messageShown then
|
||||
if (not Jobs or not next(Jobs)) then
|
||||
debugPrint("^4Debug^7: ^2Waiting for Jobs to be loaded")
|
||||
end
|
||||
if (not Items or not next(Items)) then
|
||||
debugPrint("^4Debug^7: ^2Waiting for Items to be loaded")
|
||||
end
|
||||
if (not Vehicles or not next(Vehicles)) then
|
||||
debugPrint("^4Debug^7: ^2Waiting for Vehicles to be loaded")
|
||||
end
|
||||
end
|
||||
messageShown = true
|
||||
--print((GetGameTimer() - startTime) < timeout)
|
||||
Wait(1000)
|
||||
debugPrint("Waiting for Jobs, Items, and Vehicles to be loaded")
|
||||
if Jobs and Items and Vehicles then
|
||||
print("^6Bridge^7: ^2Jobs, Items, and Vehicles Loaded^7.")
|
||||
--print("^6Bridge^7: ^2Jobs, Items, and Vehicles Loaded^7.")
|
||||
loaded = true
|
||||
break
|
||||
end
|
||||
loop += 1
|
||||
end
|
||||
if not loaded then
|
||||
print("^4Error^7: ^2Timeout reached while waiting for shared load^7.")
|
||||
print("^4Error^7: ^1Timeout reached while waiting for shared load^7.")
|
||||
return false
|
||||
else
|
||||
return true
|
||||
|
||||
@@ -1,25 +1,8 @@
|
||||
--[[
|
||||
Resource Initialization Module
|
||||
--------------------------------
|
||||
This module initializes and loads shared data (Items, Vehicles, Jobs, Gangs) from the
|
||||
various frameworks/inventory systems (OX, QB, ESX, etc.). It also corrects export names,
|
||||
caches framework exports into simple variables, and prints debug information if enabled.
|
||||
]]
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Global Variable Initialization
|
||||
-------------------------------------------------------------
|
||||
Items, Vehicles, Jobs, Gangs, Core = {}, nil, nil, nil, nil
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Correct QB Inventory Export
|
||||
-------------------------------------------------------------
|
||||
-- Correct ps-invetory to ls-inventory if somehow you still have that
|
||||
-- Shared Exports Initialization
|
||||
Exports.PSInv = isStarted("lj-inventory") and "lj-inventory" or Exports.PSInv
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Framework Exports and Inventory Identifiers
|
||||
-------------------------------------------------------------
|
||||
OXLibExport, QBXExport, QBExport, ESXExport, OXCoreExport =
|
||||
Exports.OXLibExport or "",
|
||||
Exports.QBXExport or "",
|
||||
@@ -37,310 +20,83 @@ OXInv, QBInv, PSInv, QSInv, CoreInv, CodeMInv, OrigenInv, TgiannInv =
|
||||
Exports.OrigenInv or "",
|
||||
Exports.TgiannInv or ""
|
||||
|
||||
RSGExport, RSGInv =
|
||||
Exports.RSGExport or "",
|
||||
Exports.RSGInv or ""
|
||||
|
||||
RSGExport, RSGInv = Exports.RSGExport or "", Exports.RSGInv or ""
|
||||
QBMenuExport = Exports.QBMenuExport or ""
|
||||
QBTargetExport, OXTargetExport = Exports.QBTargetExport or "", Exports.OXTargetExport or ""
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Debug: Print Found Exports
|
||||
-------------------------------------------------------------
|
||||
-- Print a list of all exports that are currently started (if debugMode is enabled).
|
||||
for _, v in pairs(Exports) do
|
||||
if isStarted(v) then
|
||||
debugPrint("^6Bridge^7: '^3"..v.."^7' export found")
|
||||
end
|
||||
end
|
||||
|
||||
OxPlayer = nil
|
||||
if isStarted(OXCoreExport) then
|
||||
if not isServer() then
|
||||
OxPlayer = Ox.GetPlayer()
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Resource Variables for Items, Jobs, and Vehicles
|
||||
-------------------------------------------------------------
|
||||
local itemResource, jobResource, vehResource = "", "", ""
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Loading Items
|
||||
-------------------------------------------------------------
|
||||
-- Load and compile shared items from the detected inventory system.
|
||||
if isStarted(OXInv) then
|
||||
itemResource = OXInv
|
||||
Items = exports[OXInv]:Items()
|
||||
|
||||
-- Add weapons to Items from QBXCore if available
|
||||
if isStarted(QBXExport) then
|
||||
local tempWeapons = exports[QBExport]:GetCoreObject().Shared.Weapons
|
||||
for k, v in pairs(tempWeapons) do
|
||||
local tempWeaponInfo = exports[OXInv]:Items(v.name)
|
||||
local weight = 0
|
||||
if tempWeaponInfo then
|
||||
weight = tempWeaponInfo.weight
|
||||
end
|
||||
if not Items[v.name] then
|
||||
Items[v.name] = {
|
||||
name = v.name,
|
||||
label = v.label,
|
||||
type = "weapon",
|
||||
ammotype = v.ammotype or "AMMO_PISTOL",
|
||||
weight = weight,
|
||||
image = v.image or (v.name..".png"),
|
||||
description = v.label or "",
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
for k, v in pairs(Items) do
|
||||
if v.client and v.client.image then
|
||||
Items[k].image = (v.client.image):gsub("nui://"..OXInv.."/web/images/", "")
|
||||
else
|
||||
Items[k].image = k..".png"
|
||||
end
|
||||
Items[k].hunger = v.client and v.client.hunger or nil
|
||||
Items[k].thirst = v.client and v.client.thirst or nil
|
||||
end
|
||||
|
||||
elseif isStarted(QBExport) then
|
||||
itemResource = QBExport
|
||||
Core = Core or exports[QBExport]:GetCoreObject()
|
||||
Items = Core and Core.Shared.Items or nil
|
||||
CreateThread(function()
|
||||
while not Items or not next(Items) do
|
||||
Items = exports[QBExport]:GetCoreObject().Shared.Items
|
||||
Wait(1000)
|
||||
end
|
||||
end)
|
||||
if isStarted(QBExport) and not isStarted(QBXExport) then
|
||||
RegisterNetEvent('QBCore:Client:UpdateObject', function()
|
||||
Core = Core or exports[QBExport]:GetCoreObject()
|
||||
Items = Core and Core.Shared.Items or nil
|
||||
end)
|
||||
end
|
||||
|
||||
elseif isStarted(ESXExport) then
|
||||
itemResource = ESXExport
|
||||
CreateThread(function()
|
||||
if isServer() then
|
||||
Items = ESX.GetItems()
|
||||
while not createCallback do Wait(100) end
|
||||
createCallback(getScript()..":getItems", function(source)
|
||||
return Items
|
||||
end)
|
||||
end
|
||||
if not isServer() then
|
||||
Items = triggerCallback(getScript()..":getItems")
|
||||
debugPrint("^6Bridge^7: ^2Loading ^6"..countTable(Items).." ^3Items^2 from ^7"..itemResource)
|
||||
end
|
||||
end)
|
||||
|
||||
elseif isStarted(RSGExport) then
|
||||
itemResource = RSGExport
|
||||
Core = Core or exports[RSGExport]:GetCoreObject()
|
||||
Items = Core and Core.Shared.Items or nil
|
||||
RegisterNetEvent('RSGCore:Client:UpdateObject', function()
|
||||
Core = Core or exports[RSGExport]:GetCoreObject()
|
||||
Items = Core and Core.Shared.Items or nil
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
if itemResource == nil then
|
||||
print("^4ERROR^7: ^2No Item info detected ^7- ^2Check ^3starter^1.^2lua^7")
|
||||
else
|
||||
while not Items do Wait(100) end
|
||||
debugPrint("^6Bridge^7: ^2Loading ^6"..countTable(Items).." ^3Items^2 from ^7"..itemResource)
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Loading Vehicles
|
||||
-------------------------------------------------------------
|
||||
-- Compile vehicles from the detected frameworks into a unified table.
|
||||
if isStarted(QBXExport) or isStarted(QBExport) then
|
||||
vehResource = QBExport
|
||||
Core = Core or exports[QBExport]:GetCoreObject()
|
||||
Vehicles = Core and Core.Shared.Vehicles
|
||||
if isStarted(QBExport) and not isStarted(QBXExport) then
|
||||
RegisterNetEvent('QBCore:Client:UpdateObject', function()
|
||||
Core = Core or exports[QBExport]:GetCoreObject()
|
||||
Vehicles = Core and Core.Shared.Vehicles
|
||||
end)
|
||||
end
|
||||
elseif isStarted(RSGExport) then
|
||||
Core = Core or exports[RSGExport]:GetCoreObject()
|
||||
end
|
||||
|
||||
elseif isStarted(OXCoreExport) then
|
||||
vehResource = OXCoreExport
|
||||
Vehicles = {}
|
||||
for k, v in pairs(Ox.GetVehicleData()) do
|
||||
Vehicles[k] = { model = k, hash = GetHashKey(k), price = v.price, name = v.name, brand = v.make }
|
||||
end
|
||||
|
||||
elseif isStarted(ESXExport) then
|
||||
vehResource = ESXExport
|
||||
if IsDuplicityVersion() then
|
||||
CreateThread(function()
|
||||
if isServer() then
|
||||
createCallback(getScript()..":getVehiclesPrices", function(source)
|
||||
return Vehicles
|
||||
end)
|
||||
while not MySQL do Wait(2000) print("^1Waiting for MySQL to exist") end
|
||||
Vehicles = MySQL.query.await('SELECT model, price, name FROM vehicles')
|
||||
local cache = nil
|
||||
local timeout = GetGameTimer() + 5000 -- 5 seconds max wait
|
||||
|
||||
-- Wait until jim_bridge is started and export is available
|
||||
while not cache and GetGameTimer() < timeout do
|
||||
if GetResourceState("jim_bridge"):find("start") then
|
||||
local success, result = pcall(function()
|
||||
return exports["jim_bridge"]:GetSharedData()
|
||||
end)
|
||||
if success and result then
|
||||
cache = result
|
||||
--print(json.encode(cache, {indent = true}))
|
||||
end
|
||||
end
|
||||
Wait(100)
|
||||
end
|
||||
if not isServer() then
|
||||
--while not triggerCallback do print("waiting") Wait(100) end
|
||||
local TempVehicles = triggerCallback(getScript()..":getVehiclesPrices")
|
||||
for _, v in pairs(TempVehicles) do
|
||||
Vehicles = Vehicles or {}
|
||||
|
||||
if not cache then
|
||||
print("^1ERROR^7: ^2jim_bridge export not available after timeout^7.")
|
||||
return
|
||||
end
|
||||
|
||||
Items = cache.Items
|
||||
Vehicles = cache.Vehicles
|
||||
Jobs = cache.Jobs
|
||||
Gangs = cache.Gangs
|
||||
|
||||
debugPrint("^6Bridge^7: ^2Shared cache successfully loaded from export^7.")
|
||||
end)
|
||||
else
|
||||
local hasCache = false
|
||||
-- 🔹 Client Side: Request from server
|
||||
_G.__jimBridgeDataCache = {}
|
||||
|
||||
RegisterNetEvent("jim_bridge:receiveCache", function(data)
|
||||
if not hasCache then
|
||||
_G.__jimBridgeDataCache = data
|
||||
hasCache = true
|
||||
else
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
TriggerServerEvent("jim_bridge:requestCache")
|
||||
|
||||
CreateThread(function()
|
||||
while not _G.__jimBridgeDataCache or not next(_G.__jimBridgeDataCache) do Wait(50) end
|
||||
local cache = _G.__jimBridgeDataCache
|
||||
Items = cache.Items or {}
|
||||
Vehicles = cache.Vehicles or {}
|
||||
Jobs = cache.Jobs or {}
|
||||
Gangs = cache.Gangs or {}
|
||||
|
||||
if isStarted(ESXExport) then
|
||||
for _, v in pairs(Vehicles) do
|
||||
Vehicles[v.model] = {
|
||||
model = v.model,
|
||||
hash = GetHashKey(v.model),
|
||||
hash = v.hash,
|
||||
price = v.price,
|
||||
name = v.name,
|
||||
brand = GetMakeNameFromVehicleModel(v.model):lower():gsub("^%l", string.upper)
|
||||
}
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
elseif isStarted(RSGExport) then
|
||||
vehResource = RSGExport
|
||||
Core = Core or exports[RSGExport]:GetCoreObject()
|
||||
Vehicles = Core and Core.Shared.Vehicles
|
||||
RegisterNetEvent('RSGCore:Client:UpdateObject', function()
|
||||
Core = Core or exports[RSGExport]:GetCoreObject()
|
||||
Vehicles = Core and Core.Shared.Vehicles
|
||||
end)
|
||||
end
|
||||
if vehResource == nil then
|
||||
print("^4ERROR^7: ^2No Vehicle info detected ^7- ^2Check ^3starter^1.^2lua^7")
|
||||
else
|
||||
while not Vehicles do Wait(1000) end
|
||||
debugPrint("^6Bridge^7: ^2Loading ^6"..countTable(Vehicles).." ^3Vehicles^2 from ^7"..vehResource)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Loading Jobs and Gangs
|
||||
-------------------------------------------------------------
|
||||
-- Compile jobs and gangs from the detected framework.
|
||||
if isStarted(QBXExport) then
|
||||
jobResource = QBXExport
|
||||
Core = Core or exports[QBExport]:GetCoreObject()
|
||||
Jobs, Gangs = exports[QBXExport]:GetJobs(), exports[QBXExport]:GetGangs()
|
||||
|
||||
elseif isStarted(OXCoreExport) then
|
||||
jobResource = OXCoreExport
|
||||
CreateThread(function()
|
||||
if isServer() then
|
||||
Jobs = {}
|
||||
createCallback(getScript()..":getOxGroups", function(source)
|
||||
return Jobs
|
||||
end)
|
||||
local tempJobs = MySQL.query.await('SELECT * FROM `ox_groups`')
|
||||
local tempGrades = MySQL.query.await('SELECT * FROM `ox_group_grades`')
|
||||
-- Index all grades by group
|
||||
local gradeMap = {}
|
||||
for _, grade in pairs(tempGrades) do
|
||||
gradeMap[grade.group] = gradeMap[grade.group] or {}
|
||||
gradeMap[grade.group][grade.grade] = {
|
||||
name = grade.label
|
||||
}
|
||||
end
|
||||
|
||||
-- Process jobs and attach grades
|
||||
for _, job in pairs(tempJobs) do
|
||||
Jobs[job.name] = {
|
||||
label = job.label,
|
||||
grades = gradeMap[job.name] or {}
|
||||
}
|
||||
end
|
||||
|
||||
-- Copy to Gangs
|
||||
Gangs = Jobs
|
||||
else
|
||||
Jobs = triggerCallback(getScript()..":getOxGroups")
|
||||
Gangs = Jobs
|
||||
end
|
||||
end)
|
||||
|
||||
elseif isStarted(QBExport) then
|
||||
jobResource = QBExport
|
||||
Core = Core or exports[QBExport]:GetCoreObject()
|
||||
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
|
||||
if isStarted(QBExport) and not isStarted(QBXExport) then
|
||||
RegisterNetEvent('QBCore:Client:UpdateObject', function()
|
||||
Core = exports[QBExport]:GetCoreObject()
|
||||
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
|
||||
end)
|
||||
end
|
||||
|
||||
elseif isStarted(ESXExport) then
|
||||
jobResource = ESXExport
|
||||
if isServer() then
|
||||
-- If server, create callback to get jobs
|
||||
createCallback(getScript()..":getESXJobs", function(source)
|
||||
return Jobs
|
||||
end)
|
||||
-- Populate jobs table with ESX.GetJobs()
|
||||
Jobs = ESX.GetJobs()
|
||||
--jsonPrint(Jobs)
|
||||
--If retreived jobs is empty, wait for ESX to load
|
||||
while countTable(Jobs) == 0 do
|
||||
Jobs = ESX.GetJobs()
|
||||
Wait(100)
|
||||
end
|
||||
-- Organise into a table the script can use
|
||||
for Role, Grades in pairs(Jobs) do
|
||||
|
||||
-- Check for "Boss" in name of grades
|
||||
for grade, info in pairs(Grades.grades) do
|
||||
--print(grade)
|
||||
--jsonPrint(info)
|
||||
|
||||
if info.label then
|
||||
--print(info)
|
||||
if info.label:find("boss") or info.label:find("Boss") then
|
||||
--print("Found Boss label for:", Grades.label)
|
||||
Jobs[Role].grades[grade].isBoss = true
|
||||
goto continue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If no roles with "boss" in the name, revert to max grade
|
||||
|
||||
-- Count grades
|
||||
local count = countTable(Grades.grades)
|
||||
Jobs[Role].grades[tostring(count-1)].isBoss = true
|
||||
--print(Grades.label.." Grade: "..count.." is Boss")
|
||||
::continue::
|
||||
end
|
||||
-- ESX Default doesn't have gangs, so copy jobs to gangs
|
||||
Gangs = Jobs
|
||||
end
|
||||
-- If client side, trigger callback to get jobs
|
||||
if not isServer() then
|
||||
Jobs = triggerCallback(getScript()..":getESXJobs")
|
||||
Gangs = Jobs
|
||||
end
|
||||
|
||||
elseif isStarted(RSGExport) then
|
||||
jobResource = RSGExport
|
||||
Core = Core or exports[RSGExport]:GetCoreObject()
|
||||
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
|
||||
RegisterNetEvent('RSGCore:Client:UpdateObject', function()
|
||||
Core = exports[RSGExport]:GetCoreObject()
|
||||
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
|
||||
end)
|
||||
end
|
||||
|
||||
if jobResource == nil then
|
||||
print("^4ERROR^7: ^2No Job info detected ^7- ^2Check ^3starter^1.^2lua^7")
|
||||
else
|
||||
while not Jobs do Wait(1000) end
|
||||
debugPrint("^6Bridge^7: ^2Loading ^6"..countTable(Jobs).." ^3Jobs^2 from ^7"..jobResource)
|
||||
debugPrint("^6Bridge^7: ^2Loading ^6"..countTable(Gangs).." ^3Gangs^2 from ^7"..jobResource)
|
||||
end
|
||||
Reference in New Issue
Block a user