mirror of
https://github.com/jimathy/jim_bridge.git
synced 2026-08-17 05:56:02 +01:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b07c089946 | ||
|
|
d603067c77 | ||
|
|
5a97b8f83a | ||
|
|
d0a09871c7 | ||
|
|
e87aa8d74d | ||
|
|
e204e6153d | ||
|
|
5c69f8dd28 | ||
|
|
f3fa309dbf | ||
|
|
9d74e7cb46 |
32
clientFrameworkCache.lua
Normal file
32
clientFrameworkCache.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
if _G.__bridge_cache_loaded then return end
|
||||
_G.__bridge_cache_loaded = true
|
||||
|
||||
_G.BridgeCache = {
|
||||
hasCache = false,
|
||||
data = nil,
|
||||
queue = {},
|
||||
}
|
||||
|
||||
RegisterNetEvent("jim_bridge:receiveCache", function(data)
|
||||
if _G.BridgeCache.hasCache then return end
|
||||
_G.BridgeCache.data = data
|
||||
_G.BridgeCache.hasCache = true
|
||||
|
||||
for _, cb in ipairs(_G.BridgeCache.queue) do
|
||||
cb(data)
|
||||
end
|
||||
_G.BridgeCache.queue = nil
|
||||
end)
|
||||
|
||||
-- Only send the request ONCE per client session
|
||||
TriggerServerEvent("jim_bridge:requestCache")
|
||||
|
||||
-- Exported async function
|
||||
function GetBridgeCache(callback)
|
||||
if _G.BridgeCache.hasCache then
|
||||
callback(_G.BridgeCache.data)
|
||||
else
|
||||
table.insert(_G.BridgeCache.queue, callback)
|
||||
end
|
||||
end
|
||||
exports("GetBridgeCache", GetBridgeCache)
|
||||
@@ -35,9 +35,12 @@ local Exports = {
|
||||
}
|
||||
|
||||
-- Prevent reloading if cache is already initialized
|
||||
if _G.__jimBridgeDataCache then return end
|
||||
_G.__jimBridgeDataCache = {}
|
||||
local cache = _G.__jimBridgeDataCache
|
||||
local cache = {
|
||||
Items = {},
|
||||
Vehicles = {},
|
||||
Jobs = {},
|
||||
Gangs = {},
|
||||
}
|
||||
|
||||
-- Helper function to check if resource exists in server (instead of if it is already started)
|
||||
local function checkExists(resourceName)
|
||||
@@ -62,7 +65,6 @@ if checkExists(Exports.ESXExport) then
|
||||
end
|
||||
|
||||
-- Initialize variables for caching
|
||||
local Items, Vehicles, Jobs, Gangs, Core = {}, {}, {}, {}, nil
|
||||
local itemResource, jobResource, vehResource = "N/A", "N/A", "N/A"
|
||||
|
||||
-- Print just to announce it knows the exports/scripts exist in the server
|
||||
@@ -85,22 +87,15 @@ if checkExists(Exports.OXInv) then
|
||||
return exports[Exports.OXInv]:Items()
|
||||
end)
|
||||
if success and result then
|
||||
Items = result
|
||||
end
|
||||
|
||||
if Items == nil or not next(Items) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find "..Exports.OXInv.." ^7Items ^1list^7, ^1possible error in that file^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
Items = {} -- Fallback to an empty table
|
||||
cache.Items = result
|
||||
end
|
||||
|
||||
-- Get Weapon info and duplicate them if they are uppercase
|
||||
-- (duplicate incase anything checks for the uppercase version)
|
||||
for k, v in pairs(Items) do
|
||||
for k, v in pairs(cache.Items) do
|
||||
if type(k) == "string" then
|
||||
if k:find("WEAPON") then
|
||||
Items[k:lower()] = Items[k]
|
||||
cache.Items[k:lower()] = cache.Items[k]
|
||||
end
|
||||
else
|
||||
print("^1ERROR^7: ^1Possible table inside a table, check your items.lua^7?")
|
||||
@@ -109,27 +104,48 @@ if checkExists(Exports.OXInv) then
|
||||
end
|
||||
end
|
||||
|
||||
elseif checkExists(Exports.QBXExport) then
|
||||
while GetResourceState(Exports.QBXExport) ~= "started" do Wait(100) end
|
||||
itemResource = Exports.QBXExport
|
||||
cache.Items = exports[Exports.QBExport]:GetCoreObject().Shared.Items
|
||||
-- If this is nil, they need to update to qbx_core 1.23.0+
|
||||
if not cache.Items then
|
||||
-- if their inventory doesn't allow that (they refuse to update their butchered core replacement):
|
||||
if GetResourceState(Exports.QSInv):find("start") then
|
||||
itemResource = Exports.QSInv
|
||||
cache.Items = exports[Exports.QSInv]:GetItemList()
|
||||
|
||||
elseif GetResourceState(Exports.OrigenInv):find("start") then
|
||||
itemResource = Exports.OrigenInv
|
||||
cache.Items = exports[Exports.OrigenInv]:Items()
|
||||
|
||||
elseif GetResourceState(Exports.CodeMInv):find("start") then
|
||||
itemResource = Exports.CodeMInv
|
||||
cache.Items = exports[Exports.CodeMInv]:GetItemList()
|
||||
|
||||
elseif GetResourceState(Exports.CoreInv):find("start") then
|
||||
itemResource = Exports.CoreInv
|
||||
cache.Items = exports[Exports.CoreInv]:getItemsList()
|
||||
|
||||
elseif GetResourceState(Exports.TgiannInv):find("start") then
|
||||
itemResource = Exports.TgiannInv
|
||||
cache.Items = exports[Exports.TgiannInv]:Items()
|
||||
end
|
||||
end
|
||||
|
||||
elseif checkExists(Exports.QBExport) then
|
||||
while GetResourceState(Exports.QBExport) ~= "started" do Wait(100) end
|
||||
itemResource = Exports.QBExport
|
||||
Core = exports[Exports.QBExport]:GetCoreObject()
|
||||
Items = Core.Shared.Items
|
||||
|
||||
if Items == nil or not next(Items) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find "..Exports.QBExport.." ^7Items ^1list^7, ^1possible error in that file^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
Items = {} -- Fallback to an empty table
|
||||
end
|
||||
cache.Items = exports[Exports.QBExport]:GetCoreObject().Shared.Items
|
||||
|
||||
elseif checkExists(Exports.ESXExport) then
|
||||
itemResource = Exports.ESXExport
|
||||
if GetResourceState(Exports.QSInv):find("start") then
|
||||
Items = exports[Exports.QSInv]:GetItemList()
|
||||
cache.Items = exports[Exports.QSInv]:GetItemList()
|
||||
else
|
||||
Items = ESX.GetItems()
|
||||
while not next(Items) do
|
||||
Items = ESX.GetItems()
|
||||
cache.Items = ESX.GetItems()
|
||||
while not next(cache.Items) do
|
||||
cache.Items = ESX.GetItems()
|
||||
Wait(1000)
|
||||
end
|
||||
end
|
||||
@@ -137,37 +153,26 @@ elseif checkExists(Exports.ESXExport) then
|
||||
elseif checkExists(Exports.RSGExport) then
|
||||
while GetResourceState(Exports.RSGExport) ~= "started" do Wait(100) end
|
||||
itemResource = Exports.RSGExport
|
||||
Core = exports[Exports.RSGExport]:GetCoreObject()
|
||||
Items = Core.Shared.Items
|
||||
if Items == nil or not next(Items) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find "..Exports.RSGExport.." ^7Items ^1list^7, ^1possible error in that file^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
Items = {} -- Fallback to an empty table
|
||||
end
|
||||
|
||||
cache.Items = exports[Exports.RSGExport]:GetCoreObject().Shared.Items
|
||||
end
|
||||
|
||||
---------------------
|
||||
--- Load Vehicles ---
|
||||
---------------------
|
||||
-- Vehicle loading depending on framework
|
||||
if checkExists(Exports.QBXExport) or checkExists(Exports.QBExport) then
|
||||
if checkExists(Exports.QBXExport) then
|
||||
vehResource = Exports.QBXExport
|
||||
cache.Vehicles = exports[Exports.QBExport]:GetCoreObject().Shared.Vehicles
|
||||
|
||||
elseif checkExists(Exports.QBExport)then
|
||||
vehResource = Exports.QBExport
|
||||
Core = Core or exports[Exports.QBExport]:GetCoreObject()
|
||||
Vehicles = Core.Shared.Vehicles
|
||||
if Vehicles == nil or not next(Vehicles) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find "..Exports.QBExport.." ^7Vehicles ^1list^7, ^1possible error in that file^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
Vehicles = {} -- Fallback to an empty table
|
||||
end
|
||||
cache.Vehicles = exports[Exports.QBExport]:GetCoreObject().Shared.Vehicles
|
||||
|
||||
elseif checkExists(Exports.OXCoreExport) then
|
||||
vehResource = Exports.OXCoreExport
|
||||
Vehicles = {}
|
||||
cache.Vehicles = {}
|
||||
for k, v in pairs(Ox.GetVehicleData()) do
|
||||
Vehicles[k] = {
|
||||
cache.Vehicles[k] = {
|
||||
model = k, hash = GetHashKey(k),
|
||||
price = v.price,
|
||||
name = v.name,
|
||||
@@ -178,9 +183,8 @@ elseif checkExists(Exports.OXCoreExport) then
|
||||
elseif checkExists(Exports.ESXExport) then
|
||||
vehResource = Exports.ESXExport
|
||||
while not MySQL do Wait(1000) end
|
||||
Vehicles = {}
|
||||
for _, v in pairs(MySQL.query.await('SELECT model, price, name FROM vehicles')) do
|
||||
Vehicles[v.model] = {
|
||||
cache.Vehicles[v.model] = {
|
||||
model = v.model,
|
||||
hash = GetHashKey(v.model),
|
||||
price = v.price,
|
||||
@@ -190,14 +194,7 @@ elseif checkExists(Exports.ESXExport) then
|
||||
|
||||
elseif checkExists(Exports.RSGExport) then
|
||||
vehResource = Exports.RSGExport
|
||||
Core = Core or exports[Exports.RSGExport]:GetCoreObject()
|
||||
Vehicles = Core.Shared.Vehicles
|
||||
if Vehicles == nil or not next(Vehicles) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find shared ^7Vehicles ^1table^7, ^1possible error in that file^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
Vehicles = {} -- Fallback to an empty table
|
||||
end
|
||||
cache.Vehicles = exports[Exports.RSGExport]:GetCoreObject().Shared.Vehicles
|
||||
|
||||
end
|
||||
|
||||
@@ -207,18 +204,14 @@ end
|
||||
-- Jobs loading based on framework
|
||||
if checkExists(Exports.QBXExport) then
|
||||
jobResource = Exports.QBXExport
|
||||
Core = Core or exports[Exports.QBXExport]:GetCoreObject()
|
||||
Jobs, Gangs = exports[Exports.QBXExport]:GetJobs(), exports[Exports.QBXExport]:GetGangs()
|
||||
if Jobs == nil or not next(Jobs) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find shared ^7Jobs ^1table^7, ^1possible error in that file^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
Jobs = {} -- Fallback to an empty table
|
||||
end
|
||||
cache.Jobs, cache.Gangs = exports[Exports.QBXExport]:GetJobs(), exports[Exports.QBXExport]:GetGangs()
|
||||
|
||||
elseif checkExists(Exports.QBExport) then
|
||||
jobResource = Exports.QBExport
|
||||
cache.Jobs, cache.Gangs = exports[Exports.QBExport]:GetCoreObject().Shared.Jobs, exports[Exports.QBExport]:GetCoreObject().Shared.Gangs
|
||||
|
||||
elseif checkExists(Exports.OXCoreExport) then
|
||||
jobResource = Exports.OXCoreExport
|
||||
Jobs = {}
|
||||
while not MySQL do Wait(1000) end
|
||||
local tempJobs = MySQL.query.await('SELECT * FROM `ox_groups`')
|
||||
local tempGrades = MySQL.query.await('SELECT * FROM `ox_group_grades`')
|
||||
@@ -228,34 +221,29 @@ elseif checkExists(Exports.OXCoreExport) then
|
||||
gradeMap[grade.group][grade.grade] = { name = grade.label }
|
||||
end
|
||||
for _, job in pairs(tempJobs) do
|
||||
Jobs[job.name] = {
|
||||
cache.Jobs[job.name] = {
|
||||
label = job.label,
|
||||
grades = gradeMap[job.name] or {}
|
||||
}
|
||||
end
|
||||
Gangs = Jobs
|
||||
|
||||
elseif checkExists(Exports.QBExport) then
|
||||
jobResource = Exports.QBExport
|
||||
Core = Core or exports[Exports.QBExport]:GetCoreObject()
|
||||
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
|
||||
cache.Gangs = cache.Jobs
|
||||
|
||||
elseif checkExists(Exports.ESXExport) then
|
||||
jobResource = Exports.ESXExport
|
||||
ESX = exports[Exports.ESXExport]:getSharedObject()
|
||||
Jobs = ESX.GetJobs()
|
||||
while not next(Jobs) do
|
||||
cache.Jobs = ESX.GetJobs()
|
||||
while not next(cache.Jobs) do
|
||||
Wait(100)
|
||||
Jobs = ESX.GetJobs()
|
||||
cache.Jobs = ESX.GetJobs()
|
||||
end
|
||||
for Role, Grades in pairs(Jobs) do
|
||||
for Role, Grades in pairs(cache.Jobs) do
|
||||
-- Check for if user has added grades
|
||||
if Grades.grades == nil or not next(Grades.grades) then
|
||||
goto continue
|
||||
end
|
||||
for grade, info in pairs(Grades.grades) do
|
||||
if info.label and info.label:find("[Bb]oss") then
|
||||
Jobs[Role].grades[grade].isBoss = true
|
||||
cache.Jobs[Role].grades[grade].isBoss = true
|
||||
goto continue
|
||||
end
|
||||
end
|
||||
@@ -268,64 +256,159 @@ elseif checkExists(Exports.ESXExport) then
|
||||
end
|
||||
|
||||
if highestGrade then
|
||||
Jobs[Role].grades[tostring(highestGrade)].isBoss = true
|
||||
cache.Jobs[Role].grades[tostring(highestGrade)].isBoss = true
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
Gangs = Jobs
|
||||
cache.Gangs = cache.Jobs
|
||||
|
||||
elseif checkExists(Exports.RSGExport) then
|
||||
jobResource = Exports.RSGExport
|
||||
Core = Core or exports[Exports.RSGExport]:GetCoreObject()
|
||||
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
|
||||
if Jobs == nil or not next(Jobs) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find shared ^7Jobs ^1table^7, ^1possible error in that file^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
Jobs = {} -- Fallback to an empty table
|
||||
end
|
||||
cache.Jobs, cache.Gangs = exports[Exports.RSGExport]:GetCoreObject().Shared.Jobs, exports[Exports.RSGExport]:GetCoreObject().Shared.Gangs
|
||||
|
||||
end
|
||||
|
||||
-- Save to global cache
|
||||
cache.Items = Items
|
||||
cache.Vehicles = Vehicles
|
||||
cache.Jobs = Jobs
|
||||
cache.Gangs = Gangs
|
||||
-- Fallback if nil or empty
|
||||
if cache.Items == nil or not next(cache.Items) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find "..itemResource.." ^7Items ^1list^7, ^1possible error in that file or is it empty^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
cache.Items = {} -- Fallback to an empty table
|
||||
end
|
||||
if cache.Vehicles == nil or not next(cache.Vehicles) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find "..vehResource.." ^7Vehicles ^1list^7, ^1possible error in that file or is it empty^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
cache.Vehicles = {} -- Fallback to an empty table
|
||||
end
|
||||
if cache.Jobs == nil or not next(cache.Jobs) then
|
||||
print("^1--------------------------------------------^7")
|
||||
print("^1ERROR^7: ^1Can NOT find "..jobResource.." ^7job ^1list^7, ^1possible error in that file or is it empty^7?")
|
||||
print("^1--------------------------------------------^7")
|
||||
cache.Jobs = {} -- Fallback to an empty table
|
||||
end
|
||||
|
||||
-- Auto Detection of Inventory Weight -- **EXPERIMENTAL**
|
||||
-- Forcefully load the the specified config file from inventory scripts
|
||||
-- This allows to get information required for certain functions that need to detect how much space is left in a players inventory
|
||||
-- This is born from too many tickets of me needing to explain that they need to change "InventoryWeight" to match their inv setting
|
||||
local function getInventoryConfig(resource, data)
|
||||
if data.convars then
|
||||
return function(path)
|
||||
local key = path[1]
|
||||
local convar = key == "MaxWeight" and data.convars.weight or key == "MaxSlots" and data.convars.slots
|
||||
return convar and GetConvarInt(convar.key, convar.default) or nil, "Unsupported convar path: " .. table.concat(path, ".")
|
||||
end
|
||||
end
|
||||
|
||||
local content = LoadResourceFile(resource, data.file)
|
||||
if not content then return nil, "Failed to load file" end
|
||||
|
||||
local env = {
|
||||
GetConvar = GetConvar, vector3 = vector3, Citizen = Citizen,
|
||||
GetResourceState = GetResourceState, exports = exports,
|
||||
DependencyCheck = DependencyCheck or function() return nil end,
|
||||
}
|
||||
|
||||
local fn, err = load(content, '@'..data.file, 't', env)
|
||||
if not fn then return nil, "Failed to compile config: " .. err end
|
||||
if not pcall(fn) then return nil, "Error executing config file" end
|
||||
|
||||
local cfg = env.Config or env.config
|
||||
if not cfg then return nil, "Config table not found" end
|
||||
|
||||
return function(path)
|
||||
local ref = cfg
|
||||
for _, k in ipairs(path) do
|
||||
if type(ref) ~= "table" then return nil, "Path invalid at: " .. tostring(k) end
|
||||
ref = ref[k]
|
||||
end
|
||||
return ref
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Inventory table
|
||||
local invWeightTable = {
|
||||
[Exports.OXInv] = { convars = {
|
||||
weight = { key = "inventory:weight", default = 30000 },
|
||||
slots = { key = "inventory:slots", default = 40 }
|
||||
}},
|
||||
[Exports.QBInv] = { file = "config/config.lua", path = { "MaxWeight" }, slotPath = { "MaxSlots" } },
|
||||
[Exports.JPRInv] = { file = "configs/main_config.lua", path = { "MaxInventoryWeight" }, slotPath = { "MaxInventorySlots" } },
|
||||
[Exports.PSInv] = { file = "config.lua", path = { "MaxInventoryWeight" }, slotPath = { "MaxInventorySlots" } },
|
||||
[Exports.QSInv] = { file = "config/config.lua", path = { "InventoryWeight", "weight" }, slotPath = { "InventoryWeight", "slots" } },
|
||||
[Exports.TgiannInv] = { file = "configs/config.lua", path = { "slotsMaxWeights", "player", "maxWeight" }, slotPath = { "slotsMaxWeights", "player", "slots" } },
|
||||
[Exports.CodeMInv] = { file = "config/config.lua", path = { "MaxWeight" }, slotPath = { "MaxSlots" } },
|
||||
[Exports.RSGInv] = { file = "config/config.lua", path = { "MaxWeight" }, slotPath = { "MaxSlots" } },
|
||||
--[Exports.OrigenInv] = { file = "config.lua", path = { "MaxWeight" } },
|
||||
}
|
||||
|
||||
-- Run config detection
|
||||
local invResource = ""
|
||||
for script, data in pairs(invWeightTable) do
|
||||
if checkExists(script) then
|
||||
if script == Exports.QBInv and GetResourceState(Exports.JPRInv):find("start") then return end
|
||||
|
||||
local lookup, err = getInventoryConfig(script, data)
|
||||
if not lookup then
|
||||
print(("^1ERROR^7: ^1Config loader failed from ^5%s^7: ^1%s^7"):format(script, err or "unknown"))
|
||||
break
|
||||
end
|
||||
|
||||
local function resolve(label, path)
|
||||
local val, perr = lookup(path)
|
||||
if val then
|
||||
cache["Inventory"..label] = val
|
||||
return
|
||||
end
|
||||
local warnType = label == "Weight" and "^1ERROR" or "^3WARNING"
|
||||
print(("%s^7: ^1Failed to get ^7Inventory%s ^1from ^5%s^7: ^1%s^7"):format(warnType, label, script, perr or "unknown"))
|
||||
end
|
||||
|
||||
resolve("Weight", data.path or { "MaxWeight" })
|
||||
resolve("Slots", data.slotPath or { "MaxSlots" })
|
||||
|
||||
invResource = script:gsub("-", "^7-^4"):gsub("_", "^7_^4")
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
CreateThread(function()
|
||||
local counts = {
|
||||
Items = 0,
|
||||
Vehicles = 0,
|
||||
Jobs = 0,
|
||||
Gangs = 0,
|
||||
Items = 0, Vehicles = 0, Jobs = 0, Gangs = 0,
|
||||
}
|
||||
for k, v in pairs(cache) do
|
||||
for count in pairs(v) do
|
||||
counts[k] += 1
|
||||
end
|
||||
if type(v) ~= "number" then for count in pairs(v) do counts[k] += 1 end end
|
||||
end
|
||||
print("^6FrameworkCache^7: ^2Loaded ^5"..tostring(counts.Items).."^2 Items from ^7"..itemResource)
|
||||
print("^6FrameworkCache^7: ^2Loaded ^5"..tostring(counts.Vehicles).."^2 Vehicles from ^7"..vehResource)
|
||||
print("^6FrameworkCache^7: ^2Loaded ^5"..tostring(counts.Jobs).."^2 Jobs from ^7"..jobResource)
|
||||
print("^6FrameworkCache^7: ^2Loaded ^5"..tostring(counts.Gangs).."^2 Gangs from ^7"..jobResource)
|
||||
if cache.InventoryWeight then
|
||||
print("^6FrameWorkCache^7: ^4"..invResource.."^2 InventoryWeight^7: ^3"..cache.InventoryWeight.."^7 (^3"..(cache.InventoryWeight / 1000).."kg^7)")
|
||||
end
|
||||
if cache.InventorySlots then
|
||||
print("^6FrameWorkCache^7: ^4"..invResource.."^2 InventorySlots^7: ^3"..cache.InventorySlots.."^7")
|
||||
end
|
||||
print("^6FrameworkCache^7: ^4"..itemResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Items).."^2 Items^7")
|
||||
print("^6FrameworkCache^7: ^4"..vehResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Vehicles).."^2 Vehicles^7")
|
||||
print("^6FrameworkCache^7: ^4"..jobResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Jobs).."^2 Jobs^7")
|
||||
print("^6FrameworkCache^7: ^4"..jobResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Gangs).."^2 Gangs^7")
|
||||
end)
|
||||
|
||||
RegisterNetEvent("jim_bridge:requestCache", function()
|
||||
local src = source
|
||||
TriggerClientEvent("jim_bridge:receiveCache", src, _G.__jimBridgeDataCache)
|
||||
TriggerClientEvent("jim_bridge:receiveCache", src, cache)
|
||||
end)
|
||||
|
||||
exports("GetSharedData", function()
|
||||
-- Wait for data to be ready before returning it
|
||||
local timeout = GetGameTimer() + 5000
|
||||
while (
|
||||
not _G.__jimBridgeDataCache or
|
||||
(not _G.__jimBridgeDataCache.Items or next(_G.__jimBridgeDataCache.Items) == nil) or
|
||||
(not _G.__jimBridgeDataCache.Vehicles or next(_G.__jimBridgeDataCache.Vehicles) == nil) or
|
||||
(not _G.__jimBridgeDataCache.Jobs or next(_G.__jimBridgeDataCache.Jobs) == nil)
|
||||
not cache or
|
||||
(not cache.Items or next(cache.Items) == nil) or
|
||||
(not cache.Vehicles or next(cache.Vehicles) == nil) or
|
||||
(not cache.Jobs or next(cache.Jobs) == nil)
|
||||
) and GetGameTimer() < timeout do
|
||||
Wait(50)
|
||||
end
|
||||
return _G.__jimBridgeDataCache
|
||||
return cache
|
||||
end)
|
||||
@@ -1,6 +1,6 @@
|
||||
name "Jim_Bridge"
|
||||
author "Jimathy"
|
||||
version "2.0.18"
|
||||
version "2.0.19"
|
||||
description "Framework Bridge By Jimathy"
|
||||
fx_version "cerulean"
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
||||
@@ -18,9 +18,10 @@ files {
|
||||
-- Version checker
|
||||
server_scripts {
|
||||
'frameworkCache.lua',
|
||||
'_versioncheck.lua'
|
||||
'_versioncheck.lua',
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'ui_modules/*.lua'
|
||||
'clientFrameworkCache.lua',
|
||||
'ui_modules/*.lua',
|
||||
}
|
||||
@@ -197,22 +197,23 @@ 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
|
||||
if not messageShown then
|
||||
while ((not Jobs or not next(Jobs)) or
|
||||
(not Items or not next(Items)) or
|
||||
(not Vehicles or not next(Vehicles))
|
||||
) and ((GetGameTimer() - startTime) < timeout) do
|
||||
if loop >= 3 and not messageShown then
|
||||
if (not Jobs or not next(Jobs)) then
|
||||
debugPrint("^4Debug^7: ^2Waiting for Jobs to be loaded")
|
||||
print("^4Debug^7: ^2Waiting for ^7Jobs^2 to be loaded")
|
||||
end
|
||||
if (not Items or not next(Items)) then
|
||||
debugPrint("^4Debug^7: ^2Waiting for Items to be loaded")
|
||||
print("^4Debug^7: ^2Waiting for ^7Items^2 to be loaded")
|
||||
end
|
||||
if (not Vehicles or not next(Vehicles)) then
|
||||
debugPrint("^4Debug^7: ^2Waiting for Vehicles to be loaded")
|
||||
print("^4Debug^7: ^2Waiting for ^7Vehicles^2 to be loaded")
|
||||
end
|
||||
messageShown = true
|
||||
end
|
||||
messageShown = true
|
||||
--print((GetGameTimer() - startTime) < timeout)
|
||||
Wait(1000)
|
||||
if Jobs and Items and Vehicles then
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Items, Vehicles, Jobs, Gangs, Core = {}, nil, nil, nil, nil
|
||||
Items, Vehicles, Jobs, Gangs = nil, nil, nil, nil
|
||||
|
||||
-- Shared Exports Initialization
|
||||
Exports.PSInv = isStarted("lj-inventory") and "lj-inventory" or Exports.PSInv
|
||||
@@ -33,80 +33,72 @@ end
|
||||
|
||||
|
||||
if IsDuplicityVersion() then
|
||||
CreateThread(function()
|
||||
local cache = nil
|
||||
local timeout = GetGameTimer() + 5000 -- 5 seconds max wait
|
||||
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
|
||||
-- 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
|
||||
end
|
||||
Wait(100)
|
||||
end
|
||||
Wait(100)
|
||||
end
|
||||
|
||||
if not cache then
|
||||
print("^1ERROR^7: ^2jim_bridge export not available after timeout^7.")
|
||||
return
|
||||
end
|
||||
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
|
||||
Items = cache.Items
|
||||
Vehicles = cache.Vehicles
|
||||
Jobs = cache.Jobs
|
||||
Gangs = cache.Gangs
|
||||
InventoryWeight = cache.InventoryWeight or InventoryWeight
|
||||
InventorySlots = cache.InventorySlots or 40
|
||||
|
||||
debugPrint("^6Bridge^7: ^2Shared cache successfully loaded from export^7.")
|
||||
end)
|
||||
debugPrint("^6Bridge^7: ^2Shared cache successfully loaded from export^7.")
|
||||
--print(countTable(Items), countTable(Vehicles), countTable(Jobs))
|
||||
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
|
||||
-- Shared bridge cache - prevent duplicate listeners
|
||||
exports["jim_bridge"]:GetBridgeCache(function(cache)
|
||||
Items = cache.Items or {}
|
||||
Vehicles = cache.Vehicles or {}
|
||||
Jobs = cache.Jobs or {}
|
||||
Gangs = cache.Gangs or {}
|
||||
InventoryWeight = cache.InventoryWeight or InventoryWeight
|
||||
InventorySlots = cache.InventorySlots or 50
|
||||
|
||||
if isStarted(ESXExport) then
|
||||
for _, v in pairs(Vehicles) do
|
||||
Vehicles[v.model] = {
|
||||
model = v.model,
|
||||
hash = v.hash,
|
||||
price = v.price,
|
||||
name = v.name,
|
||||
brand = GetMakeNameFromVehicleModel(v.model):lower():gsub("^%l", string.upper)
|
||||
}
|
||||
end
|
||||
end
|
||||
if isStarted(OXInv) then
|
||||
for k, v in pairsByKeys(Items) do
|
||||
local tempInfo = exports[OXInv]:Items(k)
|
||||
if tempInfo and tempInfo.client then
|
||||
Items[k].image = (tempInfo.client and tempInfo.client.image) and tempInfo.client.image:gsub("nui://"..OXInv.."/web/images/", "") or k..".png"
|
||||
Items[k].hunger = tempInfo.client and tempInfo.client.hunger
|
||||
Items[k].thirst = tempInfo.client and tempInfo.client.thirst
|
||||
CreateThread(function()
|
||||
if isStarted(ESXExport) then
|
||||
for _, v in pairs(Vehicles) do
|
||||
Vehicles[v.model] = {
|
||||
model = v.model,
|
||||
hash = v.hash,
|
||||
price = v.price,
|
||||
name = v.name,
|
||||
brand = GetMakeNameFromVehicleModel(v.model):lower():gsub("^%l", string.upper)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isStarted(OXInv) then
|
||||
for k, v in pairs(Items) do
|
||||
local tempInfo = exports[OXInv]:Items(k)
|
||||
Items[k].image = k..".png" -- Set default image
|
||||
if tempInfo and tempInfo.client then -- if client info, check for hard set image
|
||||
Items[k].image = (tempInfo.client.image) and tempInfo.client.image:gsub("nui://"..OXInv.."/web/images/", "") or Items[k].image
|
||||
Items[k].hunger = tempInfo.client.hunger
|
||||
Items[k].thirst = tempInfo.client.thirst
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
debugPrint("^6Bridge^7: ^2Shared cache successfully loaded from export^7.")
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -516,17 +516,19 @@ end
|
||||
--- ```lua
|
||||
--- TriggerServerEvent("script:server:setMetaData", { item = "drill", slot = 5, metadata = { durability = 80 } })
|
||||
--- ```
|
||||
RegisterNetEvent(getScript()..":server:setMetaData", function(data)
|
||||
local src = source
|
||||
RegisterNetEvent(getScript()..":server:setMetaData", function(data, src)
|
||||
local src = src or source
|
||||
if isStarted(QBInv) or isStarted(PSInv) or isStarted(RSGInv) or isStarted(JPRInv) then
|
||||
debugPrint(src, data.item, 1, data.slot)
|
||||
--debugPrint(src, data.item, 1, data.slot)
|
||||
local Player = Core.Functions.GetPlayer(src)
|
||||
Player.PlayerData.items[data.slot].info = data.metadata
|
||||
Player.PlayerData.items[data.slot].description = "HP : "..data.metadata.durability
|
||||
if data.metadata.durability then
|
||||
Player.PlayerData.items[data.slot].description = "HP : "..data.metadata.durability
|
||||
end
|
||||
Player.Functions.SetInventory(Player.PlayerData.items)
|
||||
|
||||
elseif isStarted(OXInv) then
|
||||
exports[OXInv]:SetDurability(src, data.slot, data.metadata.durability)
|
||||
exports[OXInv]:SetMetadata(src, data.slot, data.metadata)
|
||||
|
||||
elseif isStarted(QSInv) then
|
||||
exports[QSInv]:SetItemMetadata(src, data.slot, data.metadata)
|
||||
@@ -868,6 +870,14 @@ function getCurrentInvWeight()
|
||||
return weight
|
||||
end
|
||||
|
||||
function hasFreeInventorySlots(slots, src)
|
||||
local inv = getPlayerInv(src)
|
||||
if (countTable(inv) + slots) <= InventorySlots then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Check Item Existance - return boolean(true,false)
|
||||
-------------------------------------------------------------
|
||||
|
||||
@@ -225,7 +225,7 @@ if isStarted(PSInv) then
|
||||
return true
|
||||
end
|
||||
|
||||
if versionCompare(GetResourceMetadata("ps-inventory", "version", 0), "1.0.6") then
|
||||
if versionCompare(GetResourceMetadata(PSInv, "version", 0), "1.0.6") then
|
||||
print("^6Bridge^7: ^4"..PSInv.."^2 Version above ^31.0.6^7, ^2forcing ^1QBInvNew ^2to ^1true^7")
|
||||
QBInvNew = true
|
||||
else
|
||||
@@ -233,4 +233,4 @@ if isStarted(PSInv) then
|
||||
QBInvNew = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
19
version.txt
19
version.txt
@@ -1,17 +1,8 @@
|
||||
2.0.18
|
||||
2.0.19
|
||||
|
||||
- Fix ox_inv client item caching (images)
|
||||
- Add better checks if errors in ox_inv items and add more prominent error messages all around
|
||||
- Tidy up several debugPrints
|
||||
- Move AuthEvents to new file
|
||||
- Fix clearStash error with PSInv and JPRInv
|
||||
- Add extra trigger event for PSInv when opening stash (hopefully fix missing items for some)
|
||||
- Fix onPlayerUnloaded() not triggering
|
||||
- Add support for esx_society in openBossMenu()
|
||||
- Added support for okokbilling to billPlayer()
|
||||
- Rework progressBar and ui_modules folder
|
||||
- Rework isAnimal.lua to be more automated and smarter
|
||||
- Rework/Fix auto detection of QBInvNew
|
||||
- Add new functions to get players current Inventory Weight
|
||||
- SetMetadata function now handles full metadata, not just durability
|
||||
- Completely rework framework caching, it was lagging behind and breaking
|
||||
- Add new hasFreeInvnentorySlots() function
|
||||
- Add inv config file grabber, checks inventory configs for inventory weight/slots
|
||||
|
||||
https://github.com/jimathy/jim_bridge
|
||||
Reference in New Issue
Block a user