add basic support for RedM (RSGCore)

This commit is contained in:
Jim Shield
2025-04-07 20:52:59 +01:00
committed by GitHub
parent 4d8305c844
commit 2da2c56705
17 changed files with 552 additions and 244 deletions

View File

@@ -1,9 +1,10 @@
name "Jim_Bridge" name "Jim_RedBridge"
author "Jimathy" author "Jimathy"
version "2.0" version "2.0"
description "Framework Bridge By Jimathy" description "Framework Bridge By Jimathy"
fx_version "cerulean" fx_version "cerulean"
game "gta5" rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
games { 'gta5', 'rdr3' }
lua54 'yes' lua54 'yes'
files { files {

View File

@@ -53,6 +53,9 @@ function onPlayerLoaded(func, onStart)
elseif isStarted(OXCoreExport) then elseif isStarted(OXCoreExport) then
onPlayerFramework = OXCoreExport onPlayerFramework = OXCoreExport
AddEventHandler('ox:playerLoaded', tempFunc) AddEventHandler('ox:playerLoaded', tempFunc)
elseif isStarted(RSGExport) then
onPlayerFramework = RSGExport
AddEventHandler('RSGCore:Client:OnPlayerLoaded', tempFunc)
end end
if onPlayerFramework ~= "" then if onPlayerFramework ~= "" then
@@ -75,6 +78,7 @@ end
function onPlayerUnload(func) function onPlayerUnload(func)
AddEventHandler('QBCore:Client:OnPlayerUnload', function() func() end) AddEventHandler('QBCore:Client:OnPlayerUnload', function() func() end)
AddEventHandler('ox:playerLogout', function() func() end) AddEventHandler('ox:playerLogout', function() func() end)
AddEventHandler('RSGCore:Client:OnPlayerUnload', function() func() end)
--AddEventHandler('esx:playerLogout', function() func() end) --AddEventHandler('esx:playerLogout', function() func() end)
-- ^ Only server side for now, need a way to send it to client if not already available -- ^ Only server side for now, need a way to send it to client if not already available

View File

@@ -36,6 +36,10 @@ OXInv, QBInv, PSInv, QSInv, CoreInv, CodeMInv, OrigenInv =
Exports.CodeMInv or "", Exports.CodeMInv or "",
Exports.OrigenInv or "" Exports.OrigenInv or ""
RSGExport, RSGInv =
Exports.RSGExport or "",
Exports.RSGInv or ""
QBMenuExport = Exports.QBMenuExport or "" QBMenuExport = Exports.QBMenuExport or ""
QBTargetExport, OXTargetExport = Exports.QBTargetExport or "", Exports.OXTargetExport or "" QBTargetExport, OXTargetExport = Exports.QBTargetExport or "", Exports.OXTargetExport or ""
@@ -112,6 +116,18 @@ elseif isStarted(ESXExport) then
debugPrint("^6Bridge^7: ^2Loading ^6"..countTable(Items).." ^3Items^2 from ^7"..itemResource) debugPrint("^6Bridge^7: ^2Loading ^6"..countTable(Items).." ^3Items^2 from ^7"..itemResource)
end end
end) end)
elseif isStarted(RSGExport) then
itemResource = RSGExport
Core = Core or exports[RSGExport]:GetCoreObject()
Items = Core and Core.Shared.Items or nil
if isStarted(RSGExport) and not isStarted(QBXExport) then
RegisterNetEvent('QBCore:Client:UpdateObject', function()
Core = Core or exports[RSGExport]:GetCoreObject()
Items = Core and Core.Shared.Items or nil
end)
end
end end
if not isStarted(ESXExport) then if not isStarted(ESXExport) then
@@ -167,6 +183,17 @@ elseif isStarted(ESXExport) then
end end
end end
end) end)
elseif isStarted(RSGExport) then
Core = Core or exports[RSGExport]:GetCoreObject()
Vehicles = Core and Core.Shared.Vehicles
if isStarted(RSGExport) then
RegisterNetEvent('RSGExport:Client:UpdateObject', function()
Core = Core or exports[RSGExport]:GetCoreObject()
Vehicles = Core and Core.Shared.Vehicles
end)
end
vehResource = RSGExport
end end
if vehResource == nil then if vehResource == nil then
@@ -239,6 +266,17 @@ elseif isStarted(ESXExport) then
Gangs = Jobs Gangs = Jobs
end end
end) end)
elseif isStarted(RSGExport) then
jobResource = RSGExport
Core = Core or exports[RSGExport]:GetCoreObject()
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
if isStarted(RSGExport) and not isStarted(QBXExport) then
RegisterNetEvent('QBCore:Client:UpdateObject', function()
Core = exports[RSGExport]:GetCoreObject()
Jobs, Gangs = Core.Shared.Jobs, Core.Shared.Gangs
end)
end
end end
if not isStarted(ESXExport) and Jobs then if not isStarted(ESXExport) and Jobs then

View File

@@ -71,6 +71,16 @@ function drawText(image, input, style, oxStyleTable)
icon = nil, icon = nil,
text = text, text = text,
}) })
elseif Config.System.drawText == "red" then
-- Concatenate input lines and apply GTA style formatting.
for i = 1, #input do
if input[i] ~= "" then
text = text..input[i].."\n~q~"
end
end
TriggerEvent("jim-redui:DrawText", text)
end end
end end
@@ -91,5 +101,7 @@ function hideText()
ClearAllHelpMessages() ClearAllHelpMessages()
elseif Config.System.drawText == "esx" then elseif Config.System.drawText == "esx" then
ESX.HideUI() ESX.HideUI()
elseif Config.System.drawText == "red" then
TriggerEvent("jim-redui:HideText")
end end
end end

View File

@@ -1,165 +1,168 @@
if gameName ~= "rdr3" then
--[[ --[[
DUI Module (Experimental) DUI Module (Experimental)
-------------------------- --------------------------
This module handles the creation, modification, and removal of custom DUI (Display UI) This module handles the creation, modification, and removal of custom DUI (Display UI)
elements using runtime textures. It supports both client and server functionality to update DUI elements using runtime textures. It supports both client and server functionality to update DUI
images dynamically. images dynamically.
]] ]]
-- Create a runtime texture dictionary on the client if not running on the server. -- Create a runtime texture dictionary on the client if not running on the server.
scriptTxd = not isServer() and CreateRuntimeTxd(getScript()..'scriptTxd') or nil scriptTxd = not isServer() and CreateRuntimeTxd(getScript()..'scriptTxd') or nil
customDUIList = {} customDUIList = {}
------------------------------------------------------------- -------------------------------------------------------------
-- DUI Client Functions -- DUI Client Functions
------------------------------------------------------------- -------------------------------------------------------------
--- Creates or updates a DUI element. --- Creates or updates a DUI element.
--- ---
--- @param name string The unique name for the DUI element. --- @param name string The unique name for the DUI element.
--- @param http string The URL to load into the DUI. --- @param http string The URL to load into the DUI.
--- @param size table A table with .x and .y fields specifying the DUI dimensions. --- @param size table A table with .x and .y fields specifying the DUI dimensions.
--- @param txd table The runtime texture dictionary where the DUI texture will be created. --- @param txd table The runtime texture dictionary where the DUI texture will be created.
--- @usage --- @usage
--- ```lua --- ```lua
--- createDui("logo", "https://example.com/logo.png", { x = 512, y = 256 }, scriptTxd) --- createDui("logo", "https://example.com/logo.png", { x = 512, y = 256 }, scriptTxd)
--- ``` --- ```
function createDui(name, http, size, txd) function createDui(name, http, size, txd)
if not customDUIList[name] then if not customDUIList[name] then
local newDui = CreateDui(http, math.floor(size.x), math.floor(size.y)) local newDui = CreateDui(http, math.floor(size.x), math.floor(size.y))
while not GetDuiHandle(newDui) do Wait(0) end while not GetDuiHandle(newDui) do Wait(0) end
CreateRuntimeTextureFromDuiHandle(txd, name, GetDuiHandle(newDui)) CreateRuntimeTextureFromDuiHandle(txd, name, GetDuiHandle(newDui))
customDUIList[name] = newDui customDUIList[name] = newDui
SetDuiUrl(customDUIList[name], http) SetDuiUrl(customDUIList[name], http)
else else
SetDuiUrl(customDUIList[name], http) SetDuiUrl(customDUIList[name], http)
end
end
--- Opens a DUI selection input allowing the user to change the DUI image URL.
---
--- @param data table A table containing DUI data:
--- - name: The key name in the DUI list.
--- - texn: The texture name.
--- - texd: The texture dictionary.
--- - size: A table with .x and .y dimensions.
---
--- @usage
--- ```lua
--- DuiSelect({ name = "logo", texn = "logoTex", texd = "someTxd", size = { x = 512, y = 256 } })
--- ```
function DuiSelect(data)
local imagePreview = ""
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn and duiList[data.name][k] then
imagePreview = "<center>- Current Image -<br>" ..
"<img src="..duiList[data.name][k].url.." width=150px><br>" ..
"Size: ["..math.floor(data.size.x)..", "..math.floor(data.size.y).."]<br><br>"
end end
end end
local dialog = exports['qb-input']:ShowInput({
header = imagePreview..Loc[Config.Lan].menu["dui_new"],
submitText = Loc[Config.Lan].menu["dui_change"],
inputs = { { type = 'text', isRequired = true, name = 'url', text = Loc[Config.Lan].menu["dui_url"] } }
})
if dialog and dialog.url then
data.url = dialog.url
-- Scan URL for valid image extension and banned words.
local searchList = { "png", "jpg", "jpeg", "gif", "webp", "bmp" }
local banList = { "porn" }
local searchFound = false
for _, ext in pairs(searchList) do
if string.find(tostring(data.url), ext) then
searchFound = true
break
end
end
for _, banned in pairs(banList) do
if string.find(tostring(data.url), banned) then
searchFound = false
print("BANNED WORD: "..banned)
break
end
end
if searchFound then
TriggerServerEvent(getScript()..":Server:ChangeDUI", data)
end
end
end
--- Client event handler to update DUI elements. --- Opens a DUI selection input allowing the user to change the DUI image URL.
RegisterNetEvent(getScript()..":Client:ChangeDUI", function(data) ---
debugPrint("^6Bridge^7: ^2Receiving new DUI ^7- ^6"..data.url.."^7") --- @param data table A table containing DUI data:
if tostring(data.url) ~= "-" then --- - name: The key name in the DUI list.
createDui(data.texn, tostring(data.url), data.size, scriptTxd) --- - texn: The texture name.
AddReplaceTexture(tostring(data.texd), tostring(data.texn), getScript().."scriptTxd", tostring(data.texn)) --- - texd: The texture dictionary.
end --- - size: A table with .x and .y dimensions.
end) ---
--- @usage
--- Client event handler to clear DUI elements. --- ```lua
RegisterNetEvent(getScript()..":Client:ClearDUI", function(data) --- DuiSelect({ name = "logo", texn = "logoTex", texd = "someTxd", size = { x = 512, y = 256 } })
if customDUIList[tostring(data.texn)] then --- ```
RemoveReplaceTexture(tostring(data.texd), tostring(data.texn)) function DuiSelect(data)
if IsDuiAvailable(customDUIList[tostring(data.texn)]) then local imagePreview = ""
SetDuiUrl(customDUIList[data.name], nil)
end
end
end)
-------------------------------------------------------------
-- DUI Server Functions
-------------------------------------------------------------
--- Server event handler to change DUI settings.
--- If no URL is provided, resets to the preset value.
RegisterNetEvent(getScript()..":Server:ChangeDUI", function(data)
if not data.url then
for k, v in pairs(duiList[data.name]) do for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then if v.tex.texn == data.texn and duiList[data.name][k] then
debugPrint("^6Bridge^7: ^2Preset: ^6"..tostring(duiList[data.name][k].preset).."^7") imagePreview = "<center>- Current Image -<br>" ..
data.url = duiList[data.name][k].preset "<img src="..duiList[data.name][k].url.." width=150px><br>" ..
"Size: ["..math.floor(data.size.x)..", "..math.floor(data.size.y).."]<br><br>"
end
end
local dialog = exports['qb-input']:ShowInput({
header = imagePreview..Loc[Config.Lan].menu["dui_new"],
submitText = Loc[Config.Lan].menu["dui_change"],
inputs = { { type = 'text', isRequired = true, name = 'url', text = Loc[Config.Lan].menu["dui_url"] } }
})
if dialog and dialog.url then
data.url = dialog.url
-- Scan URL for valid image extension and banned words.
local searchList = { "png", "jpg", "jpeg", "gif", "webp", "bmp" }
local banList = { "porn" }
local searchFound = false
for _, ext in pairs(searchList) do
if string.find(tostring(data.url), ext) then
searchFound = true
break
end
end
for _, banned in pairs(banList) do
if string.find(tostring(data.url), banned) then
searchFound = false
print("BANNED WORD: "..banned)
break
end
end
if searchFound then
TriggerServerEvent(getScript()..":Server:ChangeDUI", data)
end end
end end
end end
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then --- Client event handler to update DUI elements.
duiList[data.name][k].url = data.url RegisterNetEvent(getScript()..":Client:ChangeDUI", function(data)
debugPrint("^6Bridge^7: ^2Receiving new DUI ^7- ^6"..data.url.."^7")
if tostring(data.url) ~= "-" then
createDui(data.texn, tostring(data.url), data.size, scriptTxd)
AddReplaceTexture(tostring(data.texd), tostring(data.texn), getScript().."scriptTxd", tostring(data.texn))
end end
end
debugPrint("^6Bridge^7: ^3DUI^2 Sending new DUI to all players^7 - ^6"..data.url.."^7")
TriggerClientEvent(getScript()..":Client:ChangeDUI", -1, data)
end)
--- Server event handler to clear DUI settings.
RegisterNetEvent(getScript()..":Server:ClearDUI", function(data)
if data.url == "-" then
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
duiList[data.name][k].url = "-"
end
end
end
TriggerClientEvent(getScript()..":Client:ClearDUI", -1, data)
end)
-------------------------------------------------------------
-- Resource Cleanup
-------------------------------------------------------------
onResourceStop(function()
for k, v in pairs(duiList or {}) do
for i = 1, #v do
RemoveReplaceTexture(tostring(v[i].tex.texd), tostring(v[i].tex.texn))
end
end
end, true)
-------------------------------------------------------------
-- DUI List Callback (Server)
-------------------------------------------------------------
if isServer() then
createCallback(getScript()..":Server:duiList", function(source)
return duiList
end) end)
--- Client event handler to clear DUI elements.
RegisterNetEvent(getScript()..":Client:ClearDUI", function(data)
if customDUIList[tostring(data.texn)] then
RemoveReplaceTexture(tostring(data.texd), tostring(data.texn))
if IsDuiAvailable(customDUIList[tostring(data.texn)]) then
SetDuiUrl(customDUIList[data.name], nil)
end
end
end)
-------------------------------------------------------------
-- DUI Server Functions
-------------------------------------------------------------
--- Server event handler to change DUI settings.
--- If no URL is provided, resets to the preset value.
RegisterNetEvent(getScript()..":Server:ChangeDUI", function(data)
if not data.url then
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
debugPrint("^6Bridge^7: ^2Preset: ^6"..tostring(duiList[data.name][k].preset).."^7")
data.url = duiList[data.name][k].preset
end
end
end
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
duiList[data.name][k].url = data.url
end
end
debugPrint("^6Bridge^7: ^3DUI^2 Sending new DUI to all players^7 - ^6"..data.url.."^7")
TriggerClientEvent(getScript()..":Client:ChangeDUI", -1, data)
end)
--- Server event handler to clear DUI settings.
RegisterNetEvent(getScript()..":Server:ClearDUI", function(data)
if data.url == "-" then
for k, v in pairs(duiList[data.name]) do
if v.tex.texn == data.texn then
duiList[data.name][k].url = "-"
end
end
end
TriggerClientEvent(getScript()..":Client:ClearDUI", -1, data)
end)
-------------------------------------------------------------
-- Resource Cleanup
-------------------------------------------------------------
onResourceStop(function()
for k, v in pairs(duiList or {}) do
for i = 1, #v do
RemoveReplaceTexture(tostring(v[i].tex.texd), tostring(v[i].tex.texn))
end
end
end, true)
-------------------------------------------------------------
-- DUI List Callback (Server)
-------------------------------------------------------------
if isServer() then
createCallback(getScript()..":Server:duiList", function(source)
return duiList
end)
end
end end

View File

@@ -148,6 +148,14 @@ function getPlayerInv(src)
grabInv = xPlayer.inventory grabInv = xPlayer.inventory
end end
elseif isStarted(RSGInv) then
foundInv = RSGInv
if src then
grabInv = Core.Functions.GetPlayer(src).PlayerData.items
else
grabInv = Core.Functions.GetPlayerData().items
end
else else
print("^4ERROR^7: ^2No Inventory detected ^7- ^2Check ^3starter^1.^2lua^7") print("^4ERROR^7: ^2No Inventory detected ^7- ^2Check ^3starter^1.^2lua^7")
end end

View File

@@ -74,6 +74,8 @@ function invImg(item)
imgLink = "nui://"..OrigenInv.."/html/img/"..(Items[item].image or "") imgLink = "nui://"..OrigenInv.."/html/img/"..(Items[item].image or "")
elseif isStarted(QBInv) then elseif isStarted(QBInv) then
imgLink = "nui://"..QBInv.."/html/images/"..(Items[item].image or "") imgLink = "nui://"..QBInv.."/html/images/"..(Items[item].image or "")
elseif isStarted(RSGInv) then
imgLink = "nui://"..RSGInv.."/html/images/"..(Items[item].image or "")
else else
print("^4ERROR^7: ^2No Inventory detected for invImg - Check starter.lua") print("^4ERROR^7: ^2No Inventory detected for invImg - Check starter.lua")
end end
@@ -99,12 +101,15 @@ end
--- addItem("health_potion", 2, { quality = "high" }) --- addItem("health_potion", 2, { quality = "high" })
--- ``` --- ```
function addItem(item, amount, info, src) function addItem(item, amount, info, src)
if not Items[item] then print("^6Bridge^7: ^1Error^7 - ^2Tried to give ^7'^3"..item.."^7'^2 but it doesn't exist") return end if not Items[item] then
print("^6Bridge^7: ^1Error^7 - ^2Tried to give ^7'^3"..item.."^7'^2 but it doesn't exist")
return
end
if src then if src then
TriggerEvent(getScript()..":server:toggleItem", true, item, amount, src, info) TriggerEvent(getScript()..":server:toggleItem", true, item, amount, src, info)
else else
TriggerServerEvent(getScript()..":server:toggleItem", true, item, amount, currentToken, info) TriggerServerEvent(getScript()..":server:toggleItem", true, item, amount, nil, info, nil, currentToken)
currentToken = nil -- clear client cached token currentToken = nil -- clear client cached token
end end
end end
@@ -129,6 +134,7 @@ function removeItem(item, amount, src, slot)
end end
if src then if src then
debugPrint(src)
TriggerEvent(getScript()..":server:toggleItem", false, item, amount, src, nil, slot) TriggerEvent(getScript()..":server:toggleItem", false, item, amount, src, nil, slot)
else else
TriggerServerEvent(getScript()..":server:toggleItem", false, item, amount, nil, nil, slot) TriggerServerEvent(getScript()..":server:toggleItem", false, item, amount, nil, nil, slot)
@@ -155,26 +161,33 @@ end
--- ```lua --- ```lua
--- TriggerServerEvent(getScript()..":server:toggleItem", true, "health_potion", 1) --- TriggerServerEvent(getScript()..":server:toggleItem", true, "health_potion", 1)
--- ``` --- ```
RegisterNetEvent(getScript()..":server:toggleItem", function(give, item, amount, newsrc, info, slot) RegisterNetEvent(getScript()..":server:toggleItem", function(give, item, amount, newsrc, info, slot, token)
debugPrint(GetInvokingResource())
if GetInvokingResource() and GetInvokingResource() ~= getScript() and GetInvokingResource() ~= "qb-core" then
debugPrint("^1Error^7: ^1Possible exploit^7, ^1vital function was called from an external resource^7")
return
end
if not Items[item] then if not Items[item] then
print("^6Bridge^7: ^1Error^7 - ^2Tried to "..(tostring(give) == "true" and "add" or "remove").." '^3"..item.."^7' but it doesn't exist") print("^6Bridge^7: ^1Error^7 - ^2Tried to "..(tostring(give) == "true" and "add" or "remove").." '^3"..item.."^7' but it doesn't exist")
return return
end end
local src = source or newsrc local src = newsrc or source
if (give == true or give == 1) then if (give == true or give == 1) then
if newsrc == nil then -- must be coming from client this would be blank if newsrc == nil then -- must be coming from client this would be blank
debugPrint("^1Auth^7: ^1No token recieved^7") if token == nil then
dupeWarn(src, item, "Auth: Player "..src.." attempted to spawn "..item.." without an auth token") debugPrint("^1Auth^7: ^1No token recieved^7")
else dupeWarn(src, item, "Auth: Player "..src.." attempted to spawn "..item.." without an auth token")
if type(newsrc) ~= "number" then -- checks if the newsrc is a source or token, if number its coming form the server itself else
debugPrint("^1Auth^7: ^2Auth token received^7, ^2checking against server cache^7..") if type(token) ~= "number" then -- checks if the newsrc is a source or token, if number its coming form the server itself
if newsrc ~= validTokens[src] then debugPrint("^1Auth^7: ^2Auth token received^7, ^2checking against server cache^7..")
debugPrint("^1Auth^7: ^1Tokens don't match! ^7", newsrc, validTokens[src]) if token ~= validTokens[src] then
dupeWarn(src, item, "Auth: "..src.." attempted to spawn "..item.." with an incorrect auth token") debugPrint("^1Auth^7: ^1Tokens don't match! ^7", token, validTokens[src])
else dupeWarn(src, item, "Auth: "..src.." attempted to spawn "..item.." with an incorrect auth token")
debugPrint("^1Auth^7: ^2Client and Server Auth tokens match^7!", newsrc, validTokens[src]) else
validTokens[src] = nil debugPrint("^1Auth^7: ^2Client and Server Auth tokens match^7!", token, validTokens[src])
validTokens[src] = nil
end
end end
end end
end end
@@ -230,6 +243,20 @@ RegisterNetEvent(getScript()..":server:toggleItem", function(give, item, amount,
if Config.Crafting.showItemBox then if Config.Crafting.showItemBox then
TriggerClientEvent("inventory:client:ItemBox", src, Items[item], "remove", amount or 1) TriggerClientEvent("inventory:client:ItemBox", src, Items[item], "remove", amount or 1)
end end
elseif isStarted(RSGInv) then invName = RSGInv
while remamount > 0 do
if Core.Functions.GetPlayer(src).Functions.RemoveItem(item, 1, slot) then
remamount -= 1
else
print("^1Error removing "..item.." Amount left: "..remamount)
break
end
end
if Config.Crafting.showItemBox then
TriggerClientEvent("rsg-inventory:client:ItemBox", src, Items[item], "remove", amount or 1)
end
end end
----- -----
-- Fallback for if no inventory found: -- Fallback for if no inventory found:
@@ -274,6 +301,11 @@ RegisterNetEvent(getScript()..":server:toggleItem", function(give, item, amount,
TriggerClientEvent((isStarted(QBInv) and QBInvNew and "qb-" or "").."inventory:client:ItemBox", src, Items[item], "add", amountToAdd) TriggerClientEvent((isStarted(QBInv) and QBInvNew and "qb-" or "").."inventory:client:ItemBox", src, Items[item], "add", amountToAdd)
end end
elseif isStarted(RSGInv) then invName = RSGInv
if Core.Functions.GetPlayer(src).Functions.AddItem(item, amountToAdd, nil, info) then
TriggerClientEvent("rsg-inventory:client:ItemBox", src, Items[item], "add", amountToAdd)
end
elseif isStarted(PSInv) then invName = PSInv elseif isStarted(PSInv) then invName = PSInv
if Core.Functions.GetPlayer(src).Functions.AddItem(item, amountToAdd, nil, info) then if Core.Functions.GetPlayer(src).Functions.AddItem(item, amountToAdd, nil, info) then
if Config.Crafting.showItemBox then if Config.Crafting.showItemBox then
@@ -601,7 +633,12 @@ function canCarry(itemTable, src)
resultTable[k] = exports[OrigenInv]:canCarryItem(src, k, v) resultTable[k] = exports[OrigenInv]:canCarryItem(src, k, v)
end end
elseif isStarted(QBInv) or isStarted(PSInv) then elseif isStarted(QBInv) then
for k, v in pairs(itemTable) do
resultTable[k] = exports[QBInv]:CanAddItem(src, k, v)
end
elseif isStarted(PSInv) then
local items = getPlayerInv(src) local items = getPlayerInv(src)
local totalWeight = 0 local totalWeight = 0
if not items then return false end if not items then return false end
@@ -616,6 +653,22 @@ function canCarry(itemTable, src)
resultTable[k] = (totalWeight + (itemInfo.weight * v)) <= InventoryWeight resultTable[k] = (totalWeight + (itemInfo.weight * v)) <= InventoryWeight
end end
end end
elseif isStarted(RSGInv) then
local items = getPlayerInv(src)
local totalWeight = 0
if not items then return false end
for _, item in pairs(items) do
totalWeight += (item.weight * item.amount)
end
for k, v in pairs(itemTable) do
local itemInfo = Items[k]
if not itemInfo then
resultTable[k] = true
else
resultTable[k] = (totalWeight + (itemInfo.weight * v)) <= InventoryWeight
end
end
end end
end end
return resultTable return resultTable
@@ -637,6 +690,11 @@ if isServer() then
createCallback(AuthEvent, function(source) createCallback(AuthEvent, function(source)
local src = source local src = source
local token = keyGen()..keyGen()..keyGen()..keyGen() -- Use a secure random generator here local token = keyGen()..keyGen()..keyGen()..keyGen() -- Use a secure random generator here
debugPrint(GetInvokingResource())
if GetInvokingResource() and GetInvokingResource() ~= getScript() and GetInvokingResource() ~= "qb-core" then
debugPrint("^1Error^7: ^1Possible exploit^7, ^1vital function was called from an external resource^7")
return ""
end
debugPrint("^1Auth^7:^2 Player Source^7: "..src.." ^2requested new token^7:", token) debugPrint("^1Auth^7:^2 Player Source^7: "..src.." ^2requested new token^7:", token)
validTokens[src] = token validTokens[src] = token
timeOutAuth(validTokens[src], src) -- Give script 10 seconds, then clear token timeOutAuth(validTokens[src], src) -- Give script 10 seconds, then clear token
@@ -664,6 +722,11 @@ if isServer() then
receivedEvent = {} receivedEvent = {}
createCallback(getScript()..":callback:GetAuthEvent", function(source) createCallback(getScript()..":callback:GetAuthEvent", function(source)
local src = source local src = source
debugPrint(GetInvokingResource())
if GetInvokingResource() and GetInvokingResource() ~= getScript() and GetInvokingResource() ~= "qb-core" then
debugPrint("^1Error^7: ^1Possible exploit^7, ^1vital callback was called from an external resource^7")
return ""
end
debugPrint("^1Auth^7: ^2Player Source^7: "..src.." ^2requested ^3AuthEvent^7", AuthEvent) debugPrint("^1Auth^7: ^2Player Source^7: "..src.." ^2requested ^3AuthEvent^7", AuthEvent)
if not receivedEvent[src] then receivedEvent[src] = true if not receivedEvent[src] then receivedEvent[src] = true
return AuthEvent return AuthEvent
@@ -673,8 +736,6 @@ if isServer() then
end end
end) end)
else else
onResourceStart(function() debugPrint("^1Auth^7: ^2Requesting ^3Auth Event^7")
debugPrint("^1Auth^7: ^2Requesting ^3Auth Event^7") AuthEvent = triggerCallback(getScript()..":callback:GetAuthEvent")
AuthEvent = triggerCallback(getScript()..":callback:GetAuthEvent")
end, true)
end end

View File

@@ -69,7 +69,7 @@ end
function jobCheck(job) function jobCheck(job)
local canDo = true local canDo = true
if Jobs[job] then if Jobs[job] then
if not hasJob(job) or not onDuty then if not hasJob(job) or not getPlayer().onDuty then
triggerNotify(nil, Loc[Config.Lan].error["not_clockedin"]) triggerNotify(nil, Loc[Config.Lan].error["not_clockedin"])
canDo = false canDo = false
end end
@@ -92,10 +92,10 @@ end
--- toggleDuty() -- Player receives a notification of their new duty status. --- toggleDuty() -- Player receives a notification of their new duty status.
--- ``` --- ```
function toggleDuty() function toggleDuty()
onDuty = not onDuty
if isStarted(QBExport) or isStarted(QBXExport) then if isStarted(QBExport) or isStarted(QBXExport) then
TriggerServerEvent("QBCore:ToggleDuty") TriggerServerEvent("QBCore:ToggleDuty")
else else
onDuty = not onDuty
if onDuty then if onDuty then
triggerNotify(nil, "Now on duty", "success") triggerNotify(nil, "Now on duty", "success")
else else

View File

@@ -1,3 +1,5 @@
local blipTable = {}
--- Creates a blip at specified coordinates with given properties. --- Creates a blip at specified coordinates with given properties.
-- --
-- This function adds a map blip at the provided coordinates and sets various display properties such as sprite, color, scale, and more. -- This function adds a map blip at the provided coordinates and sets various display properties such as sprite, color, scale, and more.
@@ -30,31 +32,48 @@
-- local blip = makeBlip(blipData) -- local blip = makeBlip(blipData)
-- ``` -- ```
function makeBlip(data) function makeBlip(data)
local blip = AddBlipForCoord(vec3(data.coords.x, data.coords.y, data.coords.z)) local blip = nil
SetBlipCoords(blip, data.coords.x, data.coords.y, data.coords.z) -- Manually set blip coordinates again as sometimes it just refuses if gameName == "rdr3" then
SetBlipAsShortRange(blip, true) blip = BlipAddForCoords(1664425300, data.coords.x, data.coords.y, data.coords.z)
SetBlipSprite(blip, data.sprite or 106) SetBlipSprite(blip, data.sprite or `blip_shop_market_stall`)
SetBlipColour(blip, data.col or 5) SetBlipScale(blip, data.scale or 0.2)
SetBlipScale(blip, data.scale or 0.7) SetBlipName(blip, data.name)
SetBlipDisplay(blip, data.disp or 6) --BlipSetStyle(blip, data.col or `BLIP_STYLE_CREATOR_DEFAULT`)
if data.category then SetBlipCategory(blip, data.category) end else
BeginTextCommandSetBlipName('STRING') blip = AddBlipForCoord(vec3(data.coords.x, data.coords.y, data.coords.z))
AddTextComponentString(tostring(data.name)) SetBlipCoords(blip, data.coords.x, data.coords.y, data.coords.z) -- Manually set blip coordinates again as sometimes it just refuses
EndTextCommandSetBlipName(blip) SetBlipAsShortRange(blip, true)
-- Handle preview image if certain resources are running SetBlipSprite(blip, data.sprite or 106)
if isStarted("fs_smallresources") or isStarted("blip_info") or isStarted("blipinfo") then SetBlipColour(blip, data.col or 5)
if data.preview then SetBlipScale(blip, data.scale or 0.7)
local txname = string.gsub(tostring(data.name..'preview'..string.gsub(data.coords.z, "%.", "")), "[ ()~]", "") SetBlipDisplay(blip, data.disp or 6)
if data.preview:find("http") or data.preview:find("nui") then if data.category then
createDui(txname, data.preview, vec2(512, 256), scriptTxd) SetBlipCategory(blip, data.category)
else end
CreateRuntimeTextureFromImage(scriptTxd, txname, data.preview) BeginTextCommandSetBlipName('STRING')
AddTextComponentString(tostring(data.name))
EndTextCommandSetBlipName(blip)
-- Handle preview image if certain resources are running
if isStarted("fs_smallresources") or isStarted("blip_info") or isStarted("blipinfo") then
if data.preview then
local txname = string.gsub(tostring(data.name..'preview'..string.gsub(data.coords.z, "%.", "")), "[ ()~]", "")
if data.preview:find("http") or data.preview:find("nui") then
createDui(txname, data.preview, vec2(512, 256), scriptTxd)
else
CreateRuntimeTextureFromImage(scriptTxd, txname, data.preview)
end
exports["fs_smallresources"]:SetBlipInfoImage(blip, getScript()..'scriptTxd', txname)
exports["fs_smallresources"]:SetBlipInfoTitle(blip, data.name, false)
end end
exports["fs_smallresources"]:SetBlipInfoImage(blip, getScript()..'scriptTxd', txname)
exports["fs_smallresources"]:SetBlipInfoTitle(blip, data.name, false)
end end
end end
debugPrint("^6Bridge^7: ^6Blip ^2created^7: '^6"..data.name.."^7' - '"..formatCoord(data.coords).."'") blipTable[blip] = blip
if DoesBlipExist(blip) then
debugPrint("^6Bridge^7: ^6Blip ^2created^7: '^6"..data.name.."^7' - '"..formatCoord(data.coords).."'")
else
print("Error making blip")
end
return blip return blip
end end
@@ -90,30 +109,54 @@ end
-- local blip = makeEntityBlip(blipData) -- local blip = makeEntityBlip(blipData)
-- ``` -- ```
function makeEntityBlip(data) function makeEntityBlip(data)
AddBlipForEntity(data.entity) local blip = nil
local blip = GetBlipFromEntity(data.entity) if gameName == "rdr3" then
SetBlipAsShortRange(blip, true) blip = BlipAddForEntity(1664425300, data.entity)
SetBlipSprite(blip, data.sprite or 106) SetBlipSprite(blip, data.sprite or `blip_ambient_coach`)
SetBlipColour(blip, data.col or 5) SetBlipScale(blip, data.scale or 0.2)
SetBlipScale(blip, data.scale or 0.7) SetBlipName(blip, data.name)
SetBlipDisplay(blip, data.disp or 6)
if data.category then SetBlipCategory(blip, data.category) end else
BeginTextCommandSetBlipName('STRING') AddBlipForEntity(data.entity)
AddTextComponentString(tostring(data.name)) blip = GetBlipFromEntity(data.entity)
EndTextCommandSetBlipName(blip) blipTable[blip] = blip
-- Handle preview image if certain resources are running SetBlipAsShortRange(blip, true)
if isStarted("fs_smallresources") or isStarted("blip-info") or isStarted("blipinfo") then SetBlipSprite(blip, data.sprite or 106)
if data.preview then SetBlipColour(blip, data.col or 5)
local txname = string.gsub(tostring(data.name..'preview'), "[ ()~]", "") SetBlipScale(blip, data.scale or 0.7)
if data.preview:find("http") or data.preview:find("nui") then SetBlipDisplay(blip, data.disp or 6)
createDui(txname, data.preview, vec2(512, 256), scriptTxd) if data.category then SetBlipCategory(blip, data.category) end
else BeginTextCommandSetBlipName('STRING')
CreateRuntimeTextureFromImage(scriptTxd, txname, data.preview) AddTextComponentString(tostring(data.name))
EndTextCommandSetBlipName(blip)
-- Handle preview image if certain resources are running
if isStarted("fs_smallresources") or isStarted("blip-info") or isStarted("blipinfo") then
if data.preview then
local txname = string.gsub(tostring(data.name..'preview'), "[ ()~]", "")
if data.preview:find("http") or data.preview:find("nui") then
createDui(txname, data.preview, vec2(512, 256), scriptTxd)
else
CreateRuntimeTextureFromImage(scriptTxd, txname, data.preview)
end
exports["fs_smallresources"]:SetBlipInfoImage(blip, getScript()..'previewTxd', txname)
exports["fs_smallresources"]:SetBlipInfoTitle(blip, data.name, false)
end end
exports["fs_smallresources"]:SetBlipInfoImage(blip, getScript()..'previewTxd', txname)
exports["fs_smallresources"]:SetBlipInfoTitle(blip, data.name, false)
end end
end end
debugPrint("^6Bridge^7: ^6Blip ^2created for Entity^7: '^6"..data.name.."^7'") blipTable[blip] = blip
if DoesBlipExist(blip) then
debugPrint("^6Bridge^7: ^6Blip ^2created for Entity^7: '^6"..data.name.."^7'")
else
print("Error making blip")
end
return blip return blip
end
if gameName == "rdr3" then
onResourceStop(function()
for k in pairs(blipTable) do
RemoveBlip(k)
end
end, true)
end end

View File

@@ -20,16 +20,16 @@ local Peds = {}
-- ``` -- ```
function makeDistPed(data, coords, freeze, collision, scenario, anim, synced) function makeDistPed(data, coords, freeze, collision, scenario, anim, synced)
local zoneCoords = type(data) == "table" and data.coords or coords local zoneCoords = type(data) == "table" and data.coords or coords
local randName = keyGen()..keyGen()
createCirclePoly({ createCirclePoly({
name = keyGen()..keyGen(), name = randName,
coords = vec3(zoneCoords.x, zoneCoords.y, zoneCoords.z - 1.03), coords = vec3(zoneCoords.x, zoneCoords.y, zoneCoords.z - 1.03),
radius = 50.0, radius = 50.0,
onEnter = function() onEnter = function()
Peds[#Peds + 1] = makePed(data, coords, freeze, collision, scenario, anim, synced) Peds[randName] = makePed(data, coords, freeze, collision, scenario, anim, synced)
end, end,
onExit = function() onExit = function()
DeletePed(Peds[#Peds]) DeletePed(Peds[randName])
end, end,
debug = debugMode, debug = debugMode,
}) })
@@ -114,7 +114,14 @@ function makePed(data, coords, freeze, collision, scenario, anim, synced)
else else
model = data model = data
loadModel(model) loadModel(model)
ped = CreatePed(0, model, coords.x, coords.y, coords.z - 1.03, coords.w, synced or false, false) if gameName == "rdr3" then
ped = CreatePed(model, coords.x, coords.y, coords.z - 1.03, coords.w, synced or false, false)
SetEntityVisible(ped, 1) -- SetEntityVisible
SetEntityAlpha(ped, 255, false) -- SetEntityAlpha
SetRandomOutfitVariation(ped, true) -- Invisible without
else
ped = CreatePed(0, model, coords.x, coords.y, coords.z - 1.03, coords.w, synced or false, false)
end
end end
SetEntityInvincible(ped, true) SetEntityInvincible(ped, true)
@@ -127,10 +134,13 @@ function makePed(data, coords, freeze, collision, scenario, anim, synced)
loadAnimDict(anim[1]) loadAnimDict(anim[1])
TaskPlayAnim(ped, anim[1], anim[2], 0.5, 1.0, -1, 1, 0.2, 0, 0, 0) TaskPlayAnim(ped, anim[1], anim[2], 0.5, 1.0, -1, 1, 0.2, 0, 0, 0)
end end
if DoesEntityExist(ped) then
debugPrint("^6Bridge^7: ^1Ped ^2Created^7: '^6"..ped.."^7' | ^2Hash^7: ^7'^5"..(model).."^7' | ^2Coord^7: "..formatCoord(coords)) debugPrint("^6Bridge^7: ^1Ped ^2Created^7: '^6"..ped.."^7' | ^2Hash^7: ^7'^5"..(model).."^7' | ^2Coord^7: "..formatCoord(coords))
else
print("error ped")
end
unloadModel(model) unloadModel(model)
Peds[#Peds + 1] = ped Peds[keyGen()..keyGen()] = ped
return ped return ped
end end
@@ -229,4 +239,8 @@ function GenerateRandomPedData(data)
end end
--- Cleans up all created Peds when the resource stops. --- Cleans up all created Peds when the resource stops.
onResourceStop(function() for i = 1, #Peds do DeletePed(Peds[i]) end end, true) onResourceStop(function()
for k in pairs(Peds) do
DeletePed(Peds[k])
end
end, true)

View File

@@ -28,7 +28,7 @@ function makeProp(data, freeze, synced)
debugPrint("^6Bridge^7: ^1Prop ^2Created^7: '^6"..prop.."^7' | ^2Hash^7: ^7'^6"..data.prop.."^7' | ^2Coord^7: "..formatCoord(data.coords)) debugPrint("^6Bridge^7: ^1Prop ^2Created^7: '^6"..prop.."^7' | ^2Hash^7: ^7'^6"..data.prop.."^7' | ^2Coord^7: "..formatCoord(data.coords))
SetModelAsNoLongerNeeded(data.prop) SetModelAsNoLongerNeeded(data.prop)
Props[#Props + 1] = prop Props[keyGen()..keyGen()] = prop
return prop return prop
end end
@@ -52,16 +52,16 @@ end
--- makeDistProp(propData, true, false) --- makeDistProp(propData, true, false)
--- ``` --- ```
function makeDistProp(data, freeze, synced, range) function makeDistProp(data, freeze, synced, range)
local prop = nil local name = keyGen()..keyGen()
createCirclePoly({ createCirclePoly({
name = keyGen()..keyGen(), name = name,
coords = vec3(data.coords.x, data.coords.y, data.coords.z - 1.03), coords = vec3(data.coords.x, data.coords.y, data.coords.z - 1.03),
radius = range or 50.0, radius = range or 50.0,
onEnter = function() onEnter = function()
prop = makeProp(data, freeze, synced) Props[name] = makeProp(data, freeze, synced)
end, end,
onExit = function() onExit = function()
destroyProp(prop) destroyProp(Props[name])
end, end,
debug = debugMode, debug = debugMode,
}) })
@@ -87,4 +87,8 @@ function destroyProp(entity)
end end
--- Cleans up all created props when the resource stops. --- Cleans up all created props when the resource stops.
onResourceStop(function() for i = 1, #Props do destroyProp(Props[i]) end end, true) onResourceStop(function()
for k in pairs(Props) do
destroyProp(Props[k])
end
end, true)

View File

@@ -17,12 +17,14 @@ function makeVeh(model, coords)
loadModel(model) loadModel(model)
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, coords.w, true, false) local veh = CreateVehicle(model, coords.x, coords.y, coords.z, coords.w, true, false)
SetVehicleHasBeenOwnedByPlayer(veh, true) SetVehicleHasBeenOwnedByPlayer(veh, true)
SetNetworkIdCanMigrate(NetworkGetNetworkIdFromEntity(veh), true) if gameName ~= "rdr3" then
Wait(100) SetNetworkIdCanMigrate(NetworkGetNetworkIdFromEntity(veh), true)
SetVehicleNeedsToBeHotwired(veh, false) Wait(100)
SetVehRadioStation(veh, 'OFF') SetVehicleNeedsToBeHotwired(veh, false)
SetVehicleFuelLevel(veh, 100.0) SetVehRadioStation(veh, 'OFF')
SetVehicleModKit(veh, 0) SetVehicleFuelLevel(veh, 100.0)
SetVehicleModKit(veh, 0)
end
SetVehicleOnGroundProperly(veh) SetVehicleOnGroundProperly(veh)
debugPrint("^6Bridge^7: ^1Veh ^2Created^7: '^6"..veh.."^7' | ^2Hash^7: ^7'^6"..model.."^7' | ^2Coord^7: "..formatCoord(coords)) debugPrint("^6Bridge^7: ^1Veh ^2Created^7: '^6"..veh.."^7' | ^2Hash^7: ^7'^6"..model.."^7' | ^2Coord^7: "..formatCoord(coords))

View File

@@ -93,6 +93,22 @@ function progressBar(data)
end end
}) })
elseif Config.System.ProgressBar == "red" then
-- Currently only uses jim-redui if you choose this option
if exports["jim-redui"]:progressBar({
label = data.label,
time = debugMode and 1000 or data.time,
dict = data.dict,
anim = data.anim,
flag = data.flag or 32,
task = data.task,
cancel = true,
}) then
result = true
else
result = false
end
elseif Config.System.ProgressBar == "gta" then elseif Config.System.ProgressBar == "gta" then
loadTextureDict("timerbars") loadTextureDict("timerbars")
if inProgress then return false end if inProgress then return false end

View File

@@ -76,6 +76,15 @@ function triggerNotify(title, message, type, src)
else else
TriggerClientEvent("jim-nui:client:notify'", src, type, message) TriggerClientEvent("jim-nui:client:notify'", src, type, message)
end end
elseif Config.System.Notify == "red" then
if isStarted("jim-redui") then
if not src then
TriggerEvent("jim-redui:Notify", title, message, type)
else
TriggerClientEvent("jim-redui:Notify", src, title, message, type)
end
end
end end
end end

View File

@@ -161,9 +161,14 @@ function chargePlayer(cost, moneyType, newsrc)
if moneyType == "cash" then if moneyType == "cash" then
if isStarted(OXInv) then fundResource = OXInv if isStarted(OXInv) then fundResource = OXInv
exports[OXInv]:RemoveItem(src, "money", cost) exports[OXInv]:RemoveItem(src, "money", cost)
elseif isStarted(QBExport) or isStarted(QBXExport) then fundResource = QBExport elseif isStarted(QBExport) or isStarted(QBXExport) then
fundResource = QBExport
Core.Functions.GetPlayer(src).Functions.RemoveMoney("cash", cost) Core.Functions.GetPlayer(src).Functions.RemoveMoney("cash", cost)
elseif isStarted(ESXExport) then fundResource = ESXExport elseif isStarted(RSGExport) then
fundResource = QBExport
Core.Functions.GetPlayer(src).Functions.RemoveMoney("cash", cost)
elseif isStarted(ESXExport) then
fundResource = ESXExport
ESX.GetPlayerFromId(src).removeMoney(cost, "") ESX.GetPlayerFromId(src).removeMoney(cost, "")
end end
elseif moneyType == "bank" then elseif moneyType == "bank" then
@@ -532,6 +537,27 @@ function getPlayer(source)
citizenId = info.citizenid, citizenId = info.citizenid,
} }
end end
elseif isStarted(RSGExport) then
if Core.Functions.GetPlayer then
local info = Core.Functions.GetPlayer(src).PlayerData
Player = {
firstname = info.charinfo.firstname,
lastname = info.charinfo.lastname,
name = info.charinfo.firstname.." "..info.charinfo.lastname,
cash = info.money["cash"],
bank = info.money["bank"],
source = info.source,
job = info.job.name,
jobBoss = info.job.isboss,
jobInfo = info.job,
gang = info.gang.name,
gangBoss = info.gang.isboss,
gangInfo = info.gang,
onDuty = info.job.onduty,
account = info.charinfo.account,
citizenId = info.citizenid,
}
end
else else
print("^4ERROR^7: ^2No Core detected for getPlayer() - Check starter.lua") print("^4ERROR^7: ^2No Core detected for getPlayer() - Check starter.lua")
end end
@@ -614,6 +640,26 @@ function getPlayer(source)
account = info.charinfo.account, account = info.charinfo.account,
citizenId = info.citizenid, citizenId = info.citizenid,
} }
elseif isStarted(RSGExport) then
local info = nil
Core.Functions.GetPlayerData(function(PlayerData) info = PlayerData end)
Player = {
firstname = info.charinfo.firstname,
lastname = info.charinfo.lastname,
name = info.charinfo.firstname.." "..info.charinfo.lastname,
cash = info.money["cash"],
bank = info.money["bank"],
source = info.source,
job = info.job.name,
jobBoss = info.job.isboss,
jobInfo = info.job,
gang = info.gang.name,
gangBoss = info.gang.isboss,
gangInfo = info.gang,
onDuty = info.job.onduty,
account = info.charinfo.account,
citizenId = info.citizenid,
}
else else
print("^4ERROR^7: ^2No Core detected for hasJob ^7- ^2Check ^3starter^1.^2lua^7") print("^4ERROR^7: ^2No Core detected for hasJob ^7- ^2Check ^3starter^1.^2lua^7")
end end

View File

@@ -78,6 +78,47 @@ function makeInstructionalButtons(info)
DrawScaleformMovieFullscreen(build, 255, 255, 255, 255, 0) DrawScaleformMovieFullscreen(build, 255, 255, 255, 255, 0)
end end
-- EXPERIMENTAL --
-- RedM Button Prompts --
-- Creates the promot, then shows it, this needs to be run in a loop
local promptGroups = {}
function makeRedInstructionalButtons(info, title)
if not promptGroups[title] then -- Create group if not exists
promptGroups[title] = {
title = CreateVarString(10, 'LITERAL_STRING', title),
id = GetRandomIntInRange(0, 0xffffff),
prompts = {},
}
for i = 1, #info do
promptGroups[title].prompts[i] = {
keys = info[i].keys,
text = info[i].text,
}
local keyTitle = CreateVarString(10, 'LITERAL_STRING', info[i].text)
-- Create one prompt per entry
local promptSet = UiPromptRegisterBegin()
-- Register all keys for this prompt
for k = 1, #info[i].keys do
PromptSetControlAction(promptSet, info[i].keys[k])
end
PromptSetText(promptSet, keyTitle)
PromptSetEnabled(promptSet, true)
PromptSetVisible(promptSet, true)
PromptSetGroup(promptSet, promptGroups[title].id)
PromptRegisterEnd(promptSet)
end
end
PromptSetActiveGroupThisFrame(promptGroups[title].id, promptGroups[title].title)
end
onResourceStop(function()
for k, v in pairs(promptGroups) do
print("^5GTAUI^7: ^2Removing Prompt Group^7: ^3" .. k .. "^7")
PromptDelete(promptGroups[k].id, 1)
end
end, true)
------------------------------------------------------------- -------------------------------------------------------------
-- Debug Text Display Functionality -- Debug Text Display Functionality
------------------------------------------------------------- -------------------------------------------------------------

View File

@@ -1,3 +1,5 @@
gameName = not IsDuplicityVersion() and GetCurrentGameName()
Exports = { Exports = {
QBExport = "qb-core", QBExport = "qb-core",
QBXExport = "qbx_core", QBXExport = "qbx_core",
@@ -17,7 +19,11 @@ Exports = {
QBMenuExport = "qb-menu", QBMenuExport = "qb-menu",
QBTargetExport = "qb-target", QBTargetExport = "qb-target",
OXTargetExport = "ox_target" OXTargetExport = "ox_target",
-- REDM
RSGExport = "rsg-core",
RSGInv = "rsg-inventory"
} }
-- Required variables -- Required variables
@@ -95,4 +101,4 @@ for _, v in pairs({ -- This is a specific load order
if debugMode then if debugMode then
print("^5Success^7: ^2loaded file^7: ^3"..(v):gsub("/", "^7/^3"):gsub("%.lua", "^7.lua").."^7") print("^5Success^7: ^2loaded file^7: ^3"..(v):gsub("/", "^7/^3"):gsub("%.lua", "^7.lua").."^7")
end end
end end