Compare commits

...

18 Commits

Author SHA1 Message Date
Jim Shield
ee15f3b076 Version Bump
`2.1.02` - `2.1.03`
2025-09-24 23:12:34 +01:00
Jim Shield
6919f038ee Release Notifier Push 2025-09-24 18:20:02 +01:00
Jim Shield
47029da6ed Revert "Version Bump"
This reverts commit f08638812c.
2025-09-24 14:23:43 +01:00
Jim Shield
e1d292d1bf Remove testing debug print 2025-09-24 14:09:19 +01:00
Jim Shield
f08638812c Version Bump
`2.1.02` - `2.1.03`
2025-09-24 13:36:14 +01:00
Jim Shield
de5424c506 Fix getPlayerInv() for CodeM Inventory 2025-09-24 12:30:08 +01:00
Jim Shield
b46d734442 Testing a rework _loaders.lua
Uses more specific functions per framework now for player loading in and out and optimizes use of them
2025-09-24 12:29:48 +01:00
Jim Shield
92ad96e435 Redo math for ox_inv get player current inv weight 2025-09-24 11:59:44 +01:00
Jim Shield
6166314cbf fix ox_inv current inventory weight check 2025-09-23 15:05:46 +01:00
Jim Shield
9fa8f58cfb Make ox_lib progressbars actually return false
I think this was causing progressbars to return true instead of `nil/false` somehow
this *should* make it more certain
2025-09-23 14:59:16 +01:00
Jim Shield
ed997ad8a2 fix typo breaking qb-core /commands 2025-09-23 12:00:40 +01:00
Jim Shield
20cea95783 Set previous active cam inactive
shouldn't be needed but just in case
2025-09-22 21:10:01 +01:00
Jim Shield
0dc5a45b5d Support for esx_society
`esx_society` requires societies to be registered manually before opening. this forces it

also adds full support for charging, funding and retrieving balances in `esx_society`
2025-09-22 21:08:31 +01:00
Jim Shield
54b1280bef Remove debug print 2025-09-21 12:09:12 +01:00
Jim Shield
3ac65d4630 Add "pre support" for jim-shops exploit security 2025-09-21 12:00:05 +01:00
Jim Shield
ed49876c69 Fix cleanup of targets for qb-target
Realised it was trying to remove `nil` when players were unloading/the scripts were ensured
2025-09-21 10:35:22 +01:00
Jim Shield
69d0f07bb6 Potential fix for playerInfo is nil 2025-09-20 17:56:47 +01:00
Jim Shield
b975f318a0 Fix hunger and thirst events
Missed out the math part when adding hunger and thirst to a player when eating items when I reworked the functions

should fix for all frameworks
2025-09-19 23:06:11 +01:00
12 changed files with 418 additions and 202 deletions

71
.github/workflows/notify-release.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: Discord Release Notifier
on:
# Manual or UI-published releases
release:
types: [published]
# Releases created by your tag-driven workflow
workflow_run:
workflows: ["Package & Release"] # must match the 'name:' in release.yml
types: [completed]
permissions:
contents: read
jobs:
# 1) Handle manual / UI / non-workflow-created releases
notify-from-release:
if: github.event_name == 'release' && github.event.action == 'published'
runs-on: ubuntu-latest
steps:
- name: Send release payload to Discord Bot
env:
URL: http://${{ secrets.DISCORDBOT }}:3000/github-releases
run: |
curl -sS -X POST "$URL" \
-H 'Content-Type: application/json' \
--data-binary "@$GITHUB_EVENT_PATH"
# 2) Handle releases created by your 'Package & Release' workflow
# (which wont trigger `on: release` when using GITHUB_TOKEN)
notify-from-workflow-run:
if: >
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq
- name: Fetch release JSON by tag
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
OWNER="${GITHUB_REPOSITORY%/*}"
REPO="${GITHUB_REPOSITORY#*/}"
TAG="${{ github.event.workflow_run.head_branch }}"
# head_branch is the tag name for a tag push workflow_run
curl -fsSL -H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$OWNER/$REPO/releases/tags/$TAG" \
> release.json
- name: Wrap as 'release' event payload & notify bot
env:
URL: http://${{ secrets.DISCORDBOT }}:3000/github-releases
run: |
set -euo pipefail
jq -n --slurpfile rel release.json \
--arg repo "$GITHUB_REPOSITORY" \
--arg repo_url "https://github.com/$GITHUB_REPOSITORY" \
--arg action "published" '
{ action: $action,
repository: { full_name: $repo, html_url: $repo_url },
release: $rel[0],
sender: { login: "github-actions[bot]" } }' > payload.json
curl -sS -X POST "$URL" \
-H 'Content-Type: application/json' \
--data-binary "@payload.json"

View File

@@ -1,6 +1,6 @@
name "Jim_Bridge" name "Jim_Bridge"
author "Jimathy" author "Jimathy"
version "2.1.02" version "2.1.03"
description "Framework Bridge By Jimathy" description "Framework Bridge By Jimathy"
fx_version "cerulean" 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.' rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'

View File

@@ -27,6 +27,132 @@ local function _debouncedRun(func)
end) end)
end end
local frameworkLoadFunc = {
{ framework = Exports.QBXExport,
onPlayerLoaded =
function(func)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', func)
end,
onPlayerUnload =
function(func)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', func)
end,
waitforLogin =
function(timeout)
local startTime = GetGameTimer()
while not LocalPlayer.state.isLoggedIn and (GetGameTimer() - startTime) < timeout do
Wait(100)
end
return LocalPlayer.state.isLoggedIn
end,
},
{ framework = Exports.QBExport,
onPlayerLoaded =
function(func)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', func)
end,
onPlayerUnload =
function(func)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', func)
end,
waitforLogin =
function(timeout)
local startTime = GetGameTimer()
while not LocalPlayer.state.isLoggedIn and (GetGameTimer() - startTime) < timeout do
Wait(100)
end
return LocalPlayer.state.isLoggedIn
end,
},
{ framework = Exports.ESXExport,
onPlayerLoaded =
function(func)
RegisterNetEvent("esx:playerLoaded", function()
-- make sure shared has loaded (because sql)
if waitForSharedLoad() then func() end
end)
end,
onPlayerUnload =
function(func)
RegisterNetEvent("esx:onPlayerLogout", func)
end,
waitforLogin =
function(timeout)
local startTime = GetGameTimer()
while (GetGameTimer() - startTime) < timeout do
local playerData = ESX.GetPlayerData()
if playerData and playerData.job then
return true
end
Wait(100)
end
end,
},
{ framework = Exports.OXCoreExport,
onPlayerLoaded =
function(func)
RegisterNetEvent('ox:playerLoaded', func)
end,
onPlayerUnload =
function(func)
RegisterNetEvent('ox:playerLogout', func)
end,
waitforLogin =
function(timeout)
if OxPlayer["stateId"] then
return true
end
while not OxPlayer["stateId"] do
Wait(1000)
if OxPlayer.get["stateId"] then
return true
end
end
end,
},
{ framework = Exports.RSGExport,
onPlayerLoaded =
function(func)
RegisterNetEvent('RSGCore:Client:OnPlayerLoaded', func)
end,
onPlayerUnload =
function(func)
RegisterNetEvent('RSGCore:Client:OnPlayerUnload', func)
end,
waitforLogin =
function(timeout)
local startTime = GetGameTimer()
while not LocalPlayer.state.isLoggedIn and (GetGameTimer() - startTime) < timeout do
Wait(100)
end
return LocalPlayer.state.isLoggedIn
end,
},
{ framework = Exports.VorpExport,
onPlayerLoaded =
function(func)
RegisterNetEvent('vorp_core:Client:OnPlayerSpawned', func)
end,
onPlayerUnload =
function(func)
--??
end,
waitforLogin =
function(timeout)
local startTime = GetGameTimer()
while not LocalPlayer.state.IsInSession and (GetGameTimer() - startTime) < timeout do
Wait(100)
end
return LocalPlayer.state.IsInSession
end,
},
}
------------------------------------------------------------- -------------------------------------------------------------
-- Player Loaded and Unloaded Events -- Player Loaded and Unloaded Events
------------------------------------------------------------- -------------------------------------------------------------
@@ -44,9 +170,6 @@ end
--- end, true) --- end, true)
--- ``` --- ```
function onPlayerLoaded(func, onStart) function onPlayerLoaded(func, onStart)
local onPlayerFramework = ""
local loaded = false
if onStart then if onStart then
onResourceStart(function() onResourceStart(function()
if not waitForLogin() then return end if not waitForLogin() then return end
@@ -59,34 +182,16 @@ function onPlayerLoaded(func, onStart)
_debouncedRun(func) _debouncedRun(func)
end end
if isStarted(QBExport) or isStarted(QBXExport) then for i = 1, #frameworkLoadFunc do
onPlayerFramework = QBExport local data = frameworkLoadFunc[i]
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', handler) jsonPrint(data)
if isStarted(data.framework) then
elseif isStarted(ESXExport) then debugPrint("^6Bridge^7: ^2Registering ^3"..data.framework.." ^5onPlayerLoaded^7()")
onPlayerFramework = ESXExport data.onPlayerLoaded(handler)
RegisterNetEvent('esx:playerLoaded', function() return
if waitForSharedLoad() then handler() end end
end)
elseif isStarted(OXCoreExport) then
onPlayerFramework = OXCoreExport
RegisterNetEvent('ox:playerLoaded', handler)
elseif isStarted(RSGExport) then
onPlayerFramework = RSGExport
RegisterNetEvent('RSGCore:Client:OnPlayerLoaded', handler)
elseif isStarted(VorpExport) then
onPlayerFramework = VorpExport
RegisterNetEvent('vorp_core:Client:OnPlayerSpawned', handler)
end
if onPlayerFramework ~= "" then
debugPrint("^6Bridge^7: ^2Registering ^3onPlayerLoaded^7()^2 with ^3" .. onPlayerFramework .. "^7")
else
print("^4ERROR^7: No supported core detected for onPlayerLoaded - Check starter.lua")
end end
print("^1ERROR^7: ^1No supported core detected for onPlayerLoaded - Check starter.lua^7")
end end
--- Executes a function when the player character is unloaded. --- Executes a function when the player character is unloaded.
@@ -99,15 +204,15 @@ end
--- end) --- end)
--- ``` --- ```
function onPlayerUnload(func) function onPlayerUnload(func)
debugPrint("^6Bridge^7: ^2Registering ^3onPlayerUnload^7()") for i = 1, #frameworkLoadFunc do
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() func() end) local data = frameworkLoadFunc[i]
if isStarted(data.framework) then
RegisterNetEvent('ox:playerLogout', function() func() end) debugPrint("^6Bridge^7: ^2Registering ^3"..data.framework.." ^5onPlayerUnload^7()")
data.onPlayerUnload(func)
RegisterNetEvent('RSGCore:Client:OnPlayerUnload', function() func() end) return
end
RegisterNetEvent('esx:onPlayerLogout', function() func() end) end
print("^1ERROR^7: ^1No supported core detected for onPlayerUnload - Check starter.lua^7")
end end
------------------------------------------------------------- -------------------------------------------------------------
@@ -166,51 +271,18 @@ end
--- @usage --- @usage
--- waitForLogin() --- waitForLogin()
function waitForLogin() function waitForLogin()
local timeout = 10000 -- 10 seconds in milliseconds for i = 1, #frameworkLoadFunc do
local startTime = GetGameTimer() local data = frameworkLoadFunc[i]
local loggedIn = false if isStarted(data.framework) then
debugPrint("^6Bridge^7: ^2Waiting for ^3"..data.framework.."^2 player login^7.")
if isStarted(ESXExport) then local result = data.waitforLogin(10000)
while (GetGameTimer() - startTime) < timeout do if result == true then
local playerData = ESX.GetPlayerData() debugPrint("^6Bridge^7: ^3"..data.framework.."^2 Player Login Detected^7.")
if playerData and playerData.job then else
loggedIn = true print("^4Error^7: ^2Timeout reached while waiting for player login^7.")
break
end end
Wait(100) return result
end end
elseif isStarted(OXCoreExport) then
if OxPlayer["stateId"] then
loggedIn = true
end
while not OxPlayer["stateId"] do
Wait(1000)
debugPrint("Waiting for stateId to class as logged in")
if OxPlayer.get["stateId"] then
loggedIn = true
break
end
end
elseif isStarted(VorpExport) then
-- For other frameworks, use LocalPlayer.state.isLoggedIn.
while not LocalPlayer.state.IsInSession and (GetGameTimer() - startTime) < timeout do
Wait(100)
end
loggedIn = LocalPlayer.state.IsInSession
else
-- For other frameworks, use LocalPlayer.state.isLoggedIn.
while not LocalPlayer.state.isLoggedIn and (GetGameTimer() - startTime) < timeout do
Wait(100)
end
loggedIn = LocalPlayer.state.isLoggedIn
end
if not loggedIn then
print("^4Error^7: ^2Timeout reached while waiting for player login^7.")
return false
else
debugPrint("^6Bridge^7: ^2Player Login Detected^7.")
return true
end end
end end

View File

@@ -56,7 +56,7 @@ local InvFunc = {
local weight = 0 local weight = 0
local itemcheck = getPlayerInv(src) local itemcheck = getPlayerInv(src)
for _, v in pairs(itemcheck) do for _, v in pairs(itemcheck) do
weight += ((v.weight * v.amount) or 0) weight += v.weight
end end
return weight return weight
end, end,
@@ -341,7 +341,7 @@ local InvFunc = {
local count = 0 local count = 0
for _, itemData in pairs(invCache) do for _, itemData in pairs(invCache) do
if itemData and itemData.name == item then if itemData and itemData.name == item then
count += (itemData.amount or itemData.count or 1) count += (itemData.amount or 0)
end end
end end
return count >= amount, count return count >= amount, count
@@ -384,7 +384,7 @@ local InvFunc = {
if src then if src then
grabInv = exports[CodeMInv]:GetInventory(getPlayer(src).citizenId, src) grabInv = exports[CodeMInv]:GetInventory(getPlayer(src).citizenId, src)
else else
grabInv = exports[CodeMInv]:getUserInventory() grabInv = exports[CodeMInv]:GetClientPlayerInventory()
end end
return grabInv return grabInv
end, end,
@@ -1279,6 +1279,7 @@ end
function hasItem(items, amount, src) function hasItem(items, amount, src)
local amount = amount and amount or 1 local amount = amount and amount or 1
local grabInv, foundInv = getPlayerInv(src) local grabInv, foundInv = getPlayerInv(src)
if type(items) ~= "table" then items = { [items] = amount and amount or 1, } end if type(items) ~= "table" then items = { [items] = amount and amount or 1, } end
local hasTable = {} local hasTable = {}
@@ -2516,7 +2517,7 @@ end
--- ``` --- ```
function sellAnim(data, token) function sellAnim(data, token)
if not hasItem(data.item, 1) then if not hasItem(data.item, 1) then
triggerNotify(nil, Loc[Config.Lan].error["dont_have"].." "..getItemLabel(data.item), "error") triggerNotify(nil, (Loc[Config.Lan].error["dont_have"] or "You don't have any") .." "..getItemLabel(data.item), "error")
return return
end end
@@ -2688,6 +2689,13 @@ function registerShop(name, label, items, society, coords)
shopExploitCheck = shopExploitCheck or {} shopExploitCheck = shopExploitCheck or {}
shopExploitCheck[name] = shopExploitCheck[name] or {} shopExploitCheck[name] = shopExploitCheck[name] or {}
if isStarted("jim-shops") then
-- Add support for new jim-shops registration export
if checkExportExists("jim-shops", "registerShop") then
exports["jim-shops"]:registerShop(name, label, items, society, coords)
end
end
for i = 1, #InvFunc do for i = 1, #InvFunc do
local inv = InvFunc[i] local inv = InvFunc[i]
if isStarted(inv.invName) then if isStarted(inv.invName) then

View File

@@ -33,6 +33,7 @@ local bossMenuFunc = {
{ name = "esx_society", { name = "esx_society",
openBossMenu = function(isGang, group) openBossMenu = function(isGang, group)
TriggerServerEvent(getScript()..":registerESXSociety", isGang, group)
TriggerEvent('esx_society:openBossMenu', group, function() end, { wash = false }) TriggerEvent('esx_society:openBossMenu', group, function() end, { wash = false })
end, end,
}, },
@@ -60,6 +61,20 @@ function openBossMenu(isGang, group)
end end
end end
-- Register ESX Society account in the server
RegisterNetEvent(getScript()..":registerESXSociety", function(group)
local checkExist = exports.esx_society:GetSociety(group)
if checkExist == nil then
exports.esx_society:registerSociety(
group,
Gangs[group] and Gangs[group].label or Jobs[group] and Jobs[group].label,
group,
group,
group,
{type = "public"}
)
end
end)
------------------------------------------------------------- -------------------------------------------------------------
-- Global Duty Status -- Global Duty Status

View File

@@ -71,6 +71,7 @@ function startTempCam(cam, renderTime, loadScene, filter, switchCam)
-- if moving from a cached previous cam, or you've sent a camre id for it to switch from, interpolate to it -- if moving from a cached previous cam, or you've sent a camre id for it to switch from, interpolate to it
if switchCam or cachePrevCam then if switchCam or cachePrevCam then
SetCamActiveWithInterp(cam, cachePrevCam, renderTime or 1000, 0, 0) SetCamActiveWithInterp(cam, cachePrevCam, renderTime or 1000, 0, 0)
SetCamActive(cachePrevCam, false) -- Set previous cam inactive (shouldn't be needed but just in case)
else else
SetCamActive(cam, true) SetCamActive(cam, true)
end end

View File

@@ -52,7 +52,7 @@ local progressFunc = {
if exports[OXLibExport]:progressBar(options) then if exports[OXLibExport]:progressBar(options) then
return true return true
else else
print("^1progressBar was not successful") return false
end end
end end
end, end,

View File

@@ -16,14 +16,18 @@ local hungerThirstFunc = {
setThirst = setThirst =
function(src, thirst) function(src, thirst)
local Player = Core.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('thirst', thirst) local newThirst = Player.PlayerData.metadata.thirst + thirst
TriggerClientEvent("hud:client:UpdateNeeds", src, Player.PlayerData.metadata.hunger, thirst) newThirst = (newThirst >= 100.0 and 100.0) or (newThirst <= 0 and 0) or newThirst
Player.Functions.SetMetaData('thirst', newThirst)
TriggerClientEvent("hud:client:UpdateNeeds", src, Player.PlayerData.metadata.hunger, newThirst)
end, end,
setHunger = setHunger =
function(src, hunger) function(src, hunger)
local Player = Core.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('hunger', hunger) local newHunger = Player.PlayerData.metadata.hunger + hunger
TriggerClientEvent("hud:client:UpdateNeeds", src, hunger, Player.PlayerData.metadata.thirst) newHunger = (newHunger >= 100.0 and 100.0) or (newHunger <= 0 and 0) or newHunger
Player.Functions.SetMetaData('hunger', newHunger)
TriggerClientEvent("hud:client:UpdateNeeds", src, newHunger, Player.PlayerData.metadata.thirst)
end, end,
}, },
@@ -31,14 +35,18 @@ local hungerThirstFunc = {
setThirst = setThirst =
function(src, thirst) function(src, thirst)
local Player = Core.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('thirst', thirst) local newThirst = Player.PlayerData.metadata.thirst + thirst
TriggerClientEvent("hud:client:UpdateNeeds", src, Player.PlayerData.metadata.hunger, thirst) newThirst = (newThirst >= 100.0 and 100.0) or (newThirst <= 0 and 0) or newThirst
Player.Functions.SetMetaData('thirst', newThirst)
TriggerClientEvent("hud:client:UpdateNeeds", src, Player.PlayerData.metadata.hunger, newThirst)
end, end,
setHunger = setHunger =
function(src, hunger) function(src, hunger)
local Player = Core.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('hunger', hunger) local newHunger = Player.PlayerData.metadata.hunger + hunger
TriggerClientEvent("hud:client:UpdateNeeds", src, hunger, Player.PlayerData.metadata.thirst) newHunger = (newHunger >= 100.0 and 100.0) or (newHunger <= 0 and 0) or newHunger
Player.Functions.SetMetaData('hunger', newHunger)
TriggerClientEvent("hud:client:UpdateNeeds", src, newHunger, Player.PlayerData.metadata.thirst)
end, end,
}, },
@@ -46,25 +54,29 @@ local hungerThirstFunc = {
setThirst = setThirst =
function(src, thirst) function(src, thirst)
local Player = Core.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('thirst', thirst) local newThirst = Player.PlayerData.metadata.thirst + thirst
TriggerClientEvent("hud:client:UpdateNeeds", src, Player.PlayerData.metadata.hunger, thirst) newThirst = (newThirst >= 100.0 and 100.0) or (newThirst <= 0 and 0) or newThirst
Player.Functions.SetMetaData('thirst', newThirst)
TriggerClientEvent("hud:client:UpdateNeeds", src, Player.PlayerData.metadata.hunger, newThirst)
end, end,
setHunger = setHunger =
function(src, hunger) function(src, hunger)
local Player = Core.Functions.GetPlayer(src) local Player = Core.Functions.GetPlayer(src)
Player.Functions.SetMetaData('hunger', hunger) local newHunger = Player.PlayerData.metadata.hunger + hunger
TriggerClientEvent("hud:client:UpdateNeeds", src, hunger, Player.PlayerData.metadata.thirst) newHunger = (newHunger >= 100.0 and 100.0) or (newHunger <= 0 and 0) or newHunger
Player.Functions.SetMetaData('hunger', newHunger)
TriggerClientEvent("hud:client:UpdateNeeds", src, newHunger, Player.PlayerData.metadata.thirst)
end, end,
}, },
{ framework = ESXExport, { framework = ESXExport,
setThirst = setThirst =
function(src, thirst) function(src, thirst)
TriggerClientEvent('esx_status:add', src, 'thirst', thirst) TriggerClientEvent('esx_status:add', src, 'thirst', tonumber(thirst) * 10000)
end, end,
setHunger = setHunger =
function(src, hunger) function(src, hunger)
TriggerClientEvent('esx_status:add', src, 'hunger', hunger) TriggerClientEvent('esx_status:add', src, 'hunger', tonumber(hunger) * 10000)
end, end,
}, },
} }
@@ -372,19 +384,21 @@ local hasGroupFunc = {
local hasJobFlag, duty = false, true local hasJobFlag, duty = false, true
local playerInfo = GetPlayer(src) local playerInfo = GetPlayer(src)
local jobinfo = playerInfo.job or playerInfo.PlayerData.job local jobinfo = playerInfo.job or playerInfo.PlayerData.job
if jobinfo.name == group then if jobinfo and jobinfo.name == group then
hasJobFlag = true hasJobFlag = true
duty = jobinfo.onduty duty = jobinfo.onduty
if grade and not (grade <= jobinfo.grade.level) then if grade and not (grade <= jobinfo.grade.level) then
hasJobFlag = false hasJobFlag = false
end end
return hasJobFlag, duty
end end
local ganginfo = playerInfo.gang or playerInfo.PlayerData.gang local ganginfo = playerInfo.gang or playerInfo.PlayerData.gang
if ganginfo.name == group then if ganginfo and ganginfo.name == group then
hasJobFlag = true hasJobFlag = true
if grade and not (grade <= ganginfo.grade.level) then if grade and not (grade <= ganginfo.grade.level) then
hasJobFlag = false hasJobFlag = false
end end
return hasJobFlag, duty
end end
return hasJobFlag, duty return hasJobFlag, duty
end, end,
@@ -396,7 +410,7 @@ local hasGroupFunc = {
local hasJobFlag, duty = false, true local hasJobFlag, duty = false, true
local playerInfo = GetPlayer(src) local playerInfo = GetPlayer(src)
local jobinfo = playerInfo.job or playerInfo.PlayerData.job local jobinfo = playerInfo.job or playerInfo.PlayerData.job
if jobinfo.name == group then if jobinfo and jobinfo.name == group then
hasJobFlag = true hasJobFlag = true
duty = jobinfo.onduty duty = jobinfo.onduty
if grade and not (grade <= jobinfo.grade.level) then if grade and not (grade <= jobinfo.grade.level) then
@@ -404,7 +418,7 @@ local hasGroupFunc = {
end end
end end
local ganginfo = playerInfo.gang or playerInfo.PlayerData.gang local ganginfo = playerInfo.gang or playerInfo.PlayerData.gang
if ganginfo.name == group then if ganginfo and ganginfo.name == group then
hasJobFlag = true hasJobFlag = true
if grade and not (grade <= ganginfo.grade.level) then if grade and not (grade <= ganginfo.grade.level) then
hasJobFlag = false hasJobFlag = false
@@ -434,26 +448,6 @@ local hasGroupFunc = {
end, end,
}, },
{ framework = OXCoreExport,
hasGroup =
function(group, grade, src)
local hasJobFlag, duty = false, true
if src then
local chunk = assert(load(LoadResourceFile('ox_core', ('imports/%s.lua'):format('server')), ('@@ox_core/%s'):format(file)))
chunk()
local player = Ox.GetPlayer(src)
for k, v in pairs(player.getGroups()) do
if k == group then hasJobFlag = true end
end
end
local info = OxPlayer.getGroups()
for k, v in pairs(info) do
if k == group then hasJobFlag = true break end
end
return hasJobFlag, duty
end,
},
{ framework = ESXExport, { framework = ESXExport,
hasGroup = hasGroup =
function(group, grade, src) function(group, grade, src)
@@ -479,7 +473,7 @@ local hasGroupFunc = {
local hasJobFlag, duty = false, true local hasJobFlag, duty = false, true
local playerInfo = GetPlayer(src) local playerInfo = GetPlayer(src)
local jobinfo = playerInfo.job or playerInfo.PlayerData.job local jobinfo = playerInfo.job or playerInfo.PlayerData.job
if jobinfo.name == group then if jobinfo and jobinfo.name == group then
hasJobFlag = true hasJobFlag = true
duty = jobinfo.onduty duty = jobinfo.onduty
if grade and not (grade <= jobinfo.grade.level) then if grade and not (grade <= jobinfo.grade.level) then
@@ -487,7 +481,7 @@ local hasGroupFunc = {
end end
end end
local ganginfo = playerInfo.gang or playerInfo.PlayerData.gang local ganginfo = playerInfo.gang or playerInfo.PlayerData.gang
if ganginfo.name == group then if ganginfo and ganginfo.name == group then
hasJobFlag = true hasJobFlag = true
if grade and not (grade <= ganginfo.grade.level) then if grade and not (grade <= ganginfo.grade.level) then
hasJobFlag = false hasJobFlag = false

View File

@@ -12,52 +12,6 @@
]] ]]
local societyFunc = { local societyFunc = {
{ bankName = "qb-banking",
getAccount =
function(society)
if not exports["qb-banking"]:GetAccount(society) then
if Jobs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateJobAccount(society, 0)
Wait(150)
elseif Gangs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateGangAccount(society, 0)
Wait(150)
end
end
return exports["qb-banking"]:GetAccountBalance(society)
end,
chargeSociety =
function(society, amount)
if not exports["qb-banking"]:GetAccount(society) then
if Jobs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateJobAccount(society, 0) Wait(150) -- make new account if return "null"
elseif Gangs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateGangAccount(society, 0) Wait(150) -- make new account if return "null"
end
end
exports["qb-banking"]:RemoveMoney(society, amount)
end,
fundSociety =
function(society, amount)
if not exports["qb-banking"]:GetAccount(society) then
if Jobs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateJobAccount(society, 0)
Wait(150)
elseif Gangs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateGangAccount(society, 0)
Wait(150)
end
end
exports["qb-banking"]:AddMoney(society, amount)
end,
},
{ bankName = "Renewed-Banking", { bankName = "Renewed-Banking",
getAccount = getAccount =
function(society) function(society)
@@ -129,6 +83,115 @@ local societyFunc = {
end end
end, end,
}, },
{ bankName = "qb-banking",
getAccount =
function(society)
if not exports["qb-banking"]:GetAccount(society) then
if Jobs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateJobAccount(society, 0)
Wait(150)
elseif Gangs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateGangAccount(society, 0)
Wait(150)
end
end
return exports["qb-banking"]:GetAccountBalance(society)
end,
chargeSociety =
function(society, amount)
if not exports["qb-banking"]:GetAccount(society) then
if Jobs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateJobAccount(society, 0) Wait(150) -- make new account if return "null"
elseif Gangs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateGangAccount(society, 0) Wait(150) -- make new account if return "null"
end
end
exports["qb-banking"]:RemoveMoney(society, amount)
end,
fundSociety =
function(society, amount)
if not exports["qb-banking"]:GetAccount(society) then
if Jobs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateJobAccount(society, 0)
Wait(150)
elseif Gangs[society] then
print("^6Bridge^7: ^2Making new bank account in ^7'^3qb-banking^7' ^2for ^7'^3"..society.."^7'")
exports["qb-banking"]:CreateGangAccount(society, 0)
Wait(150)
end
end
exports["qb-banking"]:AddMoney(society, amount)
end,
},
{ bankName = "esx_society",
getAccount =
function(society)
local checkExist = exports.esx_society:GetSociety(society)
if checkExist == nil then
print("^6Bridge^7: ^2Making new bank account in ^7'^3esx_society^7' ^2for ^7'^3"..society.."^7'")
exports.esx_society:registerSociety(
society,
Gangs[society] and Gangs[society].label or Jobs[society] and Jobs[society].label,
society,
society,
society,
{type = "public"}
)
end
local p = promise.new()
TriggerEvent('esx_addonaccount:getSharedAccount', checkExist.account, function(account)
p:resolve(account.money)
end)
local newAmount = Citizen.Await(p)
return newAmount
end,
chargeSociety =
function(society, amount)
local checkExist = exports.esx_society:GetSociety(society)
if checkExist == nil then
print("^6Bridge^7: ^2Making new bank account in ^7'^3esx_society^7' ^2for ^7'^3"..society.."^7'")
exports.esx_society:registerSociety(
society,
Gangs[society] and Gangs[society].label or Jobs[society] and Jobs[society].label,
society,
society,
society,
{type = "public"}
)
end
TriggerEvent('esx_addonaccount:getSharedAccount', checkExist.account, function(account)
if amount > 0 and account.money >= amount then
account.removeMoney(amount)
end
end)
end,
fundSociety =
function(society, amount)
local checkExist = exports.esx_society:GetSociety(society)
if checkExist == nil then
print("^6Bridge^7: ^2Making new bank account in ^7'^3esx_society^7' ^2for ^7'^3"..society.."^7'")
exports.esx_society:registerSociety(
society,
Gangs[society] and Gangs[society].label or Jobs[society] and Jobs[society].label,
society,
society,
society,
{type = "public"}
)
end
TriggerEvent('esx_addonaccount:getSharedAccount', checkExist.account, function(account)
account.addMoney(amount)
end)
end,
},
} }
@@ -200,14 +263,4 @@ function fundSociety(society, amount)
end end
print("^1Error^7: ^3FundSociety^7: ^2No supported banking script found") print("^1Error^7: ^3FundSociety^7: ^2No supported banking script found")
end
-- other
if isStarted("esx_society") then
createCallback(getScript()..":getESXSocietyAccount", function(source, society)
-- Example query adjust table/field names to match your esx_society implementation.
local result = MySQL.scalar.await('SELECT money FROM society_money WHERE society = ?', { society })
return result or 0
end)
end end

View File

@@ -33,7 +33,7 @@ local targetFunc = {
canInteract = opts[i].canInteract or nil, canInteract = opts[i].canInteract or nil,
} }
end end
exports[OXTargetExport]:addLocalEntity(entity, options) return exports[OXTargetExport]:addLocalEntity(entity, options)
end, end,
boxTarget = boxTarget =
@@ -105,7 +105,7 @@ local targetFunc = {
canInteract = opts[i].canInteract or nil, canInteract = opts[i].canInteract or nil,
} }
end end
exports[OXTargetExport]:addModel(models, options) return exports[OXTargetExport]:addModel(models, options)
end, end,
removeTargetEntity = removeTargetEntity =
@@ -128,7 +128,7 @@ local targetFunc = {
entityTarget = entityTarget =
function(entity, opts, dist) function(entity, opts, dist)
local options = { options = opts, distance = dist } local options = { options = opts, distance = dist }
exports[QBTargetExport]:AddTargetEntity(entity, options) return exports[QBTargetExport]:AddTargetEntity(entity, options)
end, end,
boxTarget = boxTarget =
@@ -148,7 +148,7 @@ local targetFunc = {
modelTarget = modelTarget =
function(models, opts, dist) function(models, opts, dist)
local options = { options = opts, distance = dist } local options = { options = opts, distance = dist }
exports[QBTargetExport]:AddTargetModel(models, options) return exports[QBTargetExport]:AddTargetModel(models, options)
end, end,
removeTargetEntity = removeTargetEntity =
@@ -213,11 +213,10 @@ local targetFunc = {
-- Tables for storing created targets for the fallback system and zone management. -- Tables for storing created targets for the fallback system and zone management.
local TextTargets = {} -- For fallback DrawText3D targets.
local targetEntities = {} -- For entity targets. local targetEntities = {} -- For entity targets.
local boxTargets = {} -- For box-shaped zone targets. local boxTargets = {} -- For box-shaped zone targets.
local circleTargets = {} -- For circular zone targets. local circleTargets = {} -- For circular zone targets.
local modelTargets = {}
------------------------------------------------------------- -------------------------------------------------------------
-- Entity Target Creation -- Entity Target Creation
------------------------------------------------------------- -------------------------------------------------------------
@@ -442,7 +441,7 @@ function createModelTarget(models, opts, dist)
if isStarted(script.targetName) then if isStarted(script.targetName) then
debugPrint("^6Bridge^7: ^2Creating new ^3Model ^2target with ^6"..script.targetName.."^7") debugPrint("^6Bridge^7: ^2Creating new ^3Model ^2target with ^6"..script.targetName.."^7")
local target = script.modelTarget(models, opts, dist) local target = script.modelTarget(models, opts, dist)
circleTargets[#circleTargets + 1] = target modelTargets[#modelTargets + 1] = target
return target return target
end end
end end
@@ -553,7 +552,7 @@ local function CleanupTargets()
if isStarted(OXTargetExport) then if isStarted(OXTargetExport) then
exports[OXTargetExport]:removeZone(boxTargets[i], true) exports[OXTargetExport]:removeZone(boxTargets[i], true)
elseif isStarted(QBTargetExport) then elseif isStarted(QBTargetExport) then
exports[QBTargetExport]:RemoveZone(boxTargets[i].name) exports[QBTargetExport]:RemoveZone(boxTargets[i])
end end
end end
-- Remove circle zone targets. -- Remove circle zone targets.
@@ -561,7 +560,7 @@ local function CleanupTargets()
if isStarted(OXTargetExport) then if isStarted(OXTargetExport) then
exports[OXTargetExport]:removeZone(circleTargets[i], true) exports[OXTargetExport]:removeZone(circleTargets[i], true)
elseif isStarted(QBTargetExport) then elseif isStarted(QBTargetExport) then
exports[QBTargetExport]:RemoveZone(circleTargets[i].name) exports[QBTargetExport]:RemoveZone(circleTargets[i])
end end
end end
end end

View File

@@ -1,4 +1,3 @@
--- Registers a command with the active command system. --- Registers a command with the active command system.
--- This function supports multiple command systems (OXLib, qb-core, ESX Legacy). --- This function supports multiple command systems (OXLib, qb-core, ESX Legacy).
--- ---
@@ -47,7 +46,7 @@ function registerCommand(command, options)
optionTable.helpInfo, optionTable.helpInfo,
optionTable.subText, optionTable.subText,
optionTable.argsRequired, optionTable.argsRequired,
optionTable.funt, optionTable.funct,
optionTable.restriction or nil optionTable.restriction or nil
) )
@@ -57,7 +56,7 @@ function registerCommand(command, options)
optionTable.helpInfo, optionTable.helpInfo,
optionTable.subText, optionTable.subText,
optionTable.argsRequired, optionTable.argsRequired,
optionTable.funt, optionTable.funct,
optionTable.restriction or nil optionTable.restriction or nil
) )

View File

@@ -1,9 +1,13 @@
2.1.02 2.1.03
- Script Overhaul, replace whole script - Fix hunger and thirst math (add instead of set)
- Removal of Quasar Script Support - Fix cleanup of targets qb-targets on unload
- Support Tgiann-inv's new item system - Add support for new jim-shops exploit protection
- **Hotfix for stores and stashes not registering properly** - Add full support for esx_society (fixes esx bossmenu errors)
- **Hotfix "nil" print and use .xy for distance check** - Fix possible issue with qb-core /command registering
- Make ox_lib progressbars return false correctly
- Fix ox_inv players current weight checks
- User alternate function for inventory retreival for CodeM Inv
- Rework _loaders.lua tobe more organised/optimizied
https://github.com/jimathy/jim_bridge/releases/latest https://github.com/jimathy/jim_bridge/releases/latest