Compare commits

..

20 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
Jim Shield
ce1df2c205 Version Bump 2025-09-19 17:54:45 +01:00
Jim Shield
75d8146e24 Fix nil print + use .xy for distance check 2025-09-19 17:22:40 +01:00
13 changed files with 425 additions and 231 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.01" 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

@@ -124,7 +124,6 @@ end
function distExploitCheck(table, src) function distExploitCheck(table, src)
if forceDisableExplotProtection == true then return true end if forceDisableExplotProtection == true then return true end
if not table then if not table then
print("^1Error^7: ^1This wasn^7'^1t reigstered correctly or this is an exploit attempt^1") print("^1Error^7: ^1This wasn^7'^1t reigstered correctly or this is an exploit attempt^1")
return false return false
@@ -135,7 +134,7 @@ function distExploitCheck(table, src)
local allow = false local allow = false
for i = 1, #table do for i = 1, #table do
if #(table[i].xyz - srcCoords) <= 10 then if #(table[i].xy - srcCoords.xy) <= 10 then
return true return true
else else
allow = false allow = false
@@ -143,7 +142,7 @@ function distExploitCheck(table, src)
end end
if not allow then if not allow then
print(src and ("^1Src ^3"..src.." ").."^1Tried to open a registered shop/stash from over the distance limit^7") print(src and ("^1Src ^3"..src.." ") or "", "^1Tried to open a registered shop/stash from over the distance limit^7")
return false return false
end end

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)
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 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
loggedIn = true
break
end
Wait(100)
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 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.") print("^4Error^7: ^2Timeout reached while waiting for player login^7.")
return false end
else return result
debugPrint("^6Bridge^7: ^2Player Login Detected^7.") end
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,
@@ -88,7 +88,6 @@ local InvFunc = {
inventory = items, inventory = items,
society = society, society = society,
}) })
debugPrint("^6Bridge^7: ^2Registering ^5"..OXInv.." ^3Store^7:", name, "^4Label^7: "..label)
end, end,
openStash = openStash =
function(data) function(data)
@@ -123,7 +122,6 @@ local InvFunc = {
registerStash = registerStash =
function(name, label, slots, weight, owner, coords) function(name, label, slots, weight, owner, coords)
exports[OXInv]:RegisterStash(name, label, slots or 50, weight or 4000000, owner or nil) exports[OXInv]:RegisterStash(name, label, slots or 50, weight or 4000000, owner or nil)
debugPrint("^6Bridge^7: ^2Registering ^4"..OXInv.." ^3Stash^7:", name, "^4Label^7: "..label)
end, end,
}, },
@@ -322,7 +320,6 @@ local InvFunc = {
registerStash = registerStash =
function(name, label, slots, weight, owner, coords) function(name, label, slots, weight, owner, coords)
exports[OrigenInv]:registerStash(name, label, slots or 50, weight or 4000000) exports[OrigenInv]:registerStash(name, label, slots or 50, weight or 4000000)
debugPrint("^6Bridge^7: ^2Registering ^4"..OrigenInv.." ^3Stash^7:", name, "^4Label^7: "..label)
end, end,
}, },
@@ -344,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
@@ -387,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,
@@ -514,7 +511,6 @@ local InvFunc = {
registerShop = registerShop =
function(name, label, items, society) function(name, label, items, society)
exports[TgiannInv]:RegisterShop(name, items) exports[TgiannInv]:RegisterShop(name, items)
debugPrint("^6Bridge^7: ^2Registering ^5"..TgiannInv.." ^3Store^7:", name, "^4Label^7: "..label)
end, end,
openStash = openStash =
function(data) function(data)
@@ -548,7 +544,6 @@ local InvFunc = {
registerStash = registerStash =
function(name, label, slots, weight, owner, coords) function(name, label, slots, weight, owner, coords)
exports[TgiannInv]:RegisterStash(name, label, slots or 50, weight or 4000000) exports[TgiannInv]:RegisterStash(name, label, slots or 50, weight or 4000000)
debugPrint("^6Bridge^7: ^2Registering ^4"..TgiannInv.." ^3Stash^7:", name, "^4Label^7: "..label)
end, end,
}, },
@@ -841,7 +836,6 @@ local InvFunc = {
items = items, items = items,
society = society, society = society,
}) })
debugPrint("^6Bridge^7: ^2Registering ^5"..QBInv.." ^3Store^7:", name, "^4Label^7: "..label)
end end
end, end,
openStash = openStash =
@@ -1040,7 +1034,6 @@ local InvFunc = {
items = items, items = items,
society = society, society = society,
}) })
debugPrint("^6Bridge^7: ^2Registering ^5"..PSInv.." ^3Store^7:", name, "^4Label^7: "..label)
end end
end, end,
openStash = openStash =
@@ -1206,7 +1199,6 @@ local InvFunc = {
items = items, items = items,
society = society, society = society,
}) })
debugPrint("^6Bridge^7: ^2Registering ^5"..RSGInv.." ^3Store^7:", name, "^4Label^7: "..label)
end, end,
openStash = openStash =
function(data) function(data)
@@ -1287,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 = {}
@@ -2357,6 +2350,7 @@ function registerStash(name, label, slots, weight, owner, coords)
local inv = InvFunc[i] local inv = InvFunc[i]
if isStarted(inv.invName) then if isStarted(inv.invName) then
inv.registerStash(name, label, slots, weight, owner, coords) inv.registerStash(name, label, slots, weight, owner, coords)
debugPrint("^6Bridge^7: ^2Registering ^4"..inv.invName.." ^3Stash^7:", name, "^4Label^7: "..label, coords and "- ^4Coord^7: "..formatCoord(coords) or "NO COORD SET")
break break
end end
end end
@@ -2487,6 +2481,7 @@ function sellMenu(data)
sellMenu(origData) sellMenu(origData)
end end
v.sellTable = data.sellTable[k] v.sellTable = data.sellTable[k]
v.name = data.name
sellMenu(v) sellMenu(v)
end, end,
} }
@@ -2522,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
@@ -2589,8 +2584,8 @@ RegisterNetEvent(getScript()..":Sellitems", function(data, token)
end) end)
function registerSellShop(name, coords) function registerSellShop(name, coords)
if coords and type(coords) == "vector3" then if coords then
print("Registered Sell Shop "..name.." Correctly") debugPrint("^6Bridge^7: ^2Registering ^3Sell Store^7: "..name, coords and "- ^4Coord^7: "..formatCoord(coords) or "NO COORD SET")
sellShopExploitCheck[name] = sellShopExploitCheck[name] or {} sellShopExploitCheck[name] = sellShopExploitCheck[name] or {}
sellShopExploitCheck[name][#sellShopExploitCheck[name]+1] = coords sellShopExploitCheck[name][#sellShopExploitCheck[name]+1] = coords
end end
@@ -2690,16 +2685,22 @@ end)
--- registerShop("weaponShop", "Weapon Shop", weaponItems, "society_weapons") --- registerShop("weaponShop", "Weapon Shop", weaponItems, "society_weapons")
--- ``` --- ```
function registerShop(name, label, items, society, coords) function registerShop(name, label, items, society, coords)
local shopResource = ""
-- ensure tables exist -- ensure tables exist
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
shopResource = inv.invName
inv.registerShop(name, label, items, society) inv.registerShop(name, label, items, society)
debugPrint("^6Bridge^7: ^2Registering ^5"..inv.invName.." ^3Store^7:", name, "^4Label^7: "..label, coords and "- ^4Coord^7: "..formatCoord(coords) or "NO COORD SET")
break break
end end
end end
@@ -2710,10 +2711,4 @@ function registerShop(name, label, items, society, coords)
else else
print("^3Warning^7: ^1Store ^4"..name.." ^1doesn^7'^1t have coords^7, ^1this is exploitable^7, ^1add coords to ^3regiterShop^7()") print("^3Warning^7: ^1Store ^4"..name.." ^1doesn^7'^1t have coords^7, ^1this is exploitable^7, ^1add coords to ^3regiterShop^7()")
end end
if shopResource ~= "" then
debugPrint("^6Bridge^7: ^2Registering ^5"..shopResource.." ^3Store^7:", name, "^4Label^7: "..label)
else
-- debugPrint("^1ERROR^7: ^1Couldn't find supported inventory to register shop^7:", name)
end
end end

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,
},
} }
@@ -201,13 +264,3 @@ function fundSociety(society, amount)
print("^1Error^7: ^3FundSociety^7: ^2No supported banking script found") print("^1Error^7: ^3FundSociety^7: ^2No supported banking script found")
end 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

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,17 +1,13 @@
2.1.01 2.1.03
- Script Overhaul, replace whole script - Fix hunger and thirst math (add instead of set)
- Very alpha support for VorpCore - Fix cleanup of targets qb-targets on unload
- Improve security - Add support for new jim-shops exploit protection
- Removal of Quasar Script Support - Add full support for esx_society (fixes esx bossmenu errors)
- Support Tgiann-inv's new item system - Fix possible issue with qb-core /command registering
- Refactor most multi-functions to be more optimized and smarter - Make ox_lib progressbars return false correctly
- Added multifunction bossmenu and clothing functions - Fix ox_inv players current weight checks
- Added ability to supress update notifcations in fxmanfiest.lua - User alternate function for inventory retreival for CodeM Inv
- Added coordinate checks to registerStash, registerShop and sellShop - Rework _loaders.lua tobe more organised/optimizied
- Optimize and Enhance built-in progressbar + target functions
- Improve weird multicharacter issue triggering onPlayerLoaded more than once
- Scripts that use this will need updating too, as things like stashes won't open
- **Hotfix for stores and stashes not registering properly**
https://github.com/jimathy/jim_bridge/releases/latest https://github.com/jimathy/jim_bridge/releases/latest