version '0.0.7'

This commit is contained in:
MrNewb committed 2025-01-08 06:33:31 -05:00
1 parent 89a9a371bd
commit 47977ce701
104 files changed
+5035

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
# Attributions
This project incorporates code from several libraries and resources licensed under GPLv3, as it inherits their licensing, and the creators are credited below:
## r_bridge
- **Purpose**: Code for codem-inventory bridging, targeting, and framework item registration.
- **Modifications to the code**: Code was not used for inventory, but was refrenced while doing my bridging for inventories and the idea of native helper functions came from that entirely. Targeting code still remains as is and is used as well as the method of registering usables.
- **Credit**: **r_bridge** inventory bridging code for codem-inventory is used in this. Targeting code still remains as is and is used.
[\[r_bridge\]](https://github.com/rumaier/r_bridge)
## clean_lib
- **Purpose**: Vehicle fuel, vehicle key bridging and the loading and saving methods of json files.
- **Modifications to the code**: None.
- **Credit**: **clean_lib** code is used to manage vehicle fuel and keys, bridging these systems seamlessly.
[\[clean_lib\]](https://github.com/Clean-Server-Pack/clean_lib)
## ox_lib
- **Purpose**: Utility functions for printing raycasting and point registering.
- **Credit**: **ox_lib** provides various utility functions for printing and interacting with other objects in this resource. While theres no code pulled directly from the resource, it is still the backbone to it so a thanks is nessesary.
[\[ox_lib\]](https://github.com/overextended/ox_lib)
## renewed_lib
- **Purpose**: Object placer functionality.
- **Modifications to the code**: Variable naming, added missing params for the natives used, updated a depreciated export from oxlib for the raycast camera, altered the showtext ui to now work with multiple showtextui systems, moved the text for placement into locales, the requestModel exports from ox_lib were replaced with the function my bridge uses to request models from ox_lib.
- **Credit**: **renewed_lib** code is used for its object placement snippet.
[\[renewed_lib\]](https://github.com/Renewed-Scripts/Renewed-Lib)
## duff
- **Purpose**: Version Checker.
- **Modifications to the code**: Variables removed, now will pull repo information from passed string.
- **Credit**: **duff** code was refrenced and some used for version checker formatting and print style.
[\[duff\]](https://github.com/DonHulieo/duff/blob/d89ed3b0051194babf5711114a0c437d4e41f433/server/init.lua#L10C1-L28C4)
Thank you to the creators and maintainers of these libraries/bridges/internet points for their hard work and contributions to the FiveM community.
+39
View File
@@ -0,0 +1,39 @@
# community_bridge
## By The Order of the Sacred Bridge
The **Order of the Sacred Bridge**, a fellowship born of noble intention and quiet passion, has crafted a bridge to simplify the journey of all who dare venture into the world of development. This bridge, much like a well-worn path through the woods, is modular in design, offering an array of systems and tools that serve the wanderer and the scholar alike:
- Clothing Systems
- Dispatch Systems
- Doorlock Systems
- Frameworks
- Fuel Systems
- Input Systems
- Inventory Systems
- Locale Systems
- Vehicle Key Systems
- Management Systems
- Math Library
- Menu Systems
- Notify Systems
- Phone Systems
- Progress Bars
- Target Systems
- Weather Systems
- A vast trove of helpful functions
- And many more...
As with any grand creation, this bridge also includes utility functions, some of which may be of great use, while others may seem like hidden treasures, waiting to be discovered by those with keen eyes.
This bridge proudly incorporates snippets from the wide and varied community, some of which are crafted under the honorable **GPLv3** license. All contributions are duly credited in the **Attributions** file, ensuring we respect the deeds of those who came before us and maintain our adherence to the principles of the **GPLv3**.
A **labor of love** it has been, this bridge, forged with a deep **passion for scripts** and a desire to unite the scattered folk of the development world. In the spirit of cooperation, it seeks to bring together those with differing preferences and ideas, creating something that is **entry-level**, **versatile**, and filled with **compatibility wrappers** for all the major resources. It also lays the groundwork for future resources that wish to cross its sturdy spans.
This bridge, a curious blend of its own **library** and a tool of great utility, is full of **helper functions** that will guide you on your journey, making the most complex tasks simpler and more straightforward, like a trusty map in a foreign land.
Crafted with care, the bridge is as **user-friendly** as a friendly hobbit’s home, catering to both beginners and seasoned travelers. It is a bridge of great adaptability, easily modified to suit the needs of those who walk across it.
This bridge will **not fall victim to the ego of any single individual**, for its foundation lies in the belief that any contribution of value to the community, if it adheres to the simple philosophy of **simplicity**, and ensures an easy path for all, is **welcome**.
The aim, much like the hobbits' journey to Morridor, is to create a **free, open, community-driven bridge**, one that serves the needs of the many and welcomes all who wish to add their mark to the map.
+154
View File
@@ -0,0 +1,154 @@
local Tables = Require('use/tables.lua')
local Ids = Require("use/ids.lua")
local AllInstances = {}
---@class Class
Class = {}
Class.ClassName = "Class"
Class.__call = function(this, ...)
return this:new(...)
end
Builders = {}
function Class.SetInstance(instance)
AllInstances[instance.id] = instance
end
function Class.GetInstance(id)
return AllInstances[id]
end
--- Default (empty) constructor
--- @param self Class
--- @vararg any
function Class:init(...) end
--- Creates a subclass of the current class.
--- This function copies the properties and methods of the current class to a new object.
--- It also sets up metatables to allow for object-oriented behavior, such as method calls and property access.
--- @param obj object | nil: The table to extend. If nil, a new table will be created.
--- @return obj object: The extended object with properties and methods from the given class obj.
function Class:extend(obj)
local className = obj.ClassName or "Class"
local old = Tables.DeepClone(self, {}, {components = true})
local new = Tables.DeepClone(obj, old, {ClassName = true})
new.components = self.components or {}
new.components[className] = obj
if not new.id then new.id = Ids.CreateUniqueId(new.components) end
-- create new objects directly, like o = Object()
self = setmetatable(new, Class)
if not Class.GetInstance(new.id) then Class.SetInstance(self) end
return self
end
--- Sets a property on the object. NOTE: This is mostly for internal purposes.
--- @param prop string|table: The property name or a table of properties to set.
--- @param value any: The value to set the property to.
function Class:set(prop, value)
if not value and type(prop) == "table" then
for k, v in pairs(prop) do
rawset(self._, k, v)
end
else
rawset(self._, prop, value)
end
end
--- This function is used to create a new instance of the class.
--- It calls the init function if it exists.
--- @vararg any: The arguments to pass to the init
--- @return object: The new instance of the class.
function Class:new(...)
local obj = self:extend({})
if obj.init then obj:init(...) end
return obj
end
--- This function is used to create a new instance of the class.
--- It calls the struct function if it exists.
--- @vararg object(s): List of objects to extend the class with.
--- @return object: The new instance of the class with the data and functions from the objects passed.
function class(className, ...)
local newObj = Class:extend({})
local components = table.pack(...)
newObj.ClassName = className
if components then
for k, v in pairs(components) do
local clName = v.ClassName
if not Builders[clName] then -- builders are used to reconstruct an object usually when pulled from server to client or vice versa
Builders[clName] = Tables.DeepClone(newObj)
end
end
end
if components.n > 0 then
for k, v in pairs(components) do
if k ~= "n" then
local newNewObject = nil
if v.Struct and type(v.Struct) == "function" then
newNewObject = v:Struct()
end
newObj = newObj:extend(newNewObject or v)
end
end
else
return newObj
end
return newObj
end
function reconstruct(obj)
local newTable = {}
local tbl = obj.components or {}
for k, v in pairs(tbl) do
local builder = Builders[k]
if builder then
newTable[k] = builder
end
end
return class(table.unpack(newTable))
end
--- Overwrites the type(self) value to return "Class".
--- @return string: The string "Class".
function Class:__type()
return self.ClassName or "Class"
end
--- Overwrites the call operator to call the new function. Ex: Class()
--- @vararg any: The arguments to pass to the new function.
--- @return object: The new instance of the class.
function Class:__call(...)
return self:new(...)
end
--- Checks to see if the class is an instance of the given class.
--- @param cls Class: The class to check against.
--- @return boolean: True if the class is an instance of the given class, false otherwise.
function Class:IsA(cls)
local p = promise.new()
CreateThread(function()
local m = getmetatable(self)
while m do
if m == cls then
return p:resolve(true)
end
m = getmetatable(m)
Wait(0)
end
return p:resolve(false)
end)
return Citizen.Await(p)
end
return {Class, class}
+38
View File
@@ -0,0 +1,38 @@
local classModule = Require("components/class.lua")
local _, class = table.unpack(classModule)
-- Registry to store singletons for classes
local SingletonRegistry = {}
--- @class Singleton
local Singleton = class()
Singleton.ClassName = "Singleton"
--- Ensures the class instance is a singleton.
--- If an instance already exists, it returns the existing one.
--- If not, it initializes and registers a new singleton.
function Singleton:Struct()
local className = self.ClassName or "UnnamedClass"
-- Check if the singleton already exists
if SingletonRegistry[className] then
self = SingletonRegistry[className]
return self
end
-- Register this instance as the singleton for its class
SingletonRegistry[className] = self
return self
end
--- Clears the singleton instance for this class (if needed).
function Singleton:ClearSingleton()
local destroy = self.Destroy
if destroy and type(destroy) == "function" then self:Destroy() end
local className = self.ClassName or "UnnamedClass"
SingletonRegistry[className] = nil
end
--- Returns the existing singleton for a class.
--- @param className string: The name of the class to check.
--- @return any: The singleton instance, or nil if none exists.
function Singleton.Get(className)
return SingletonRegistry[className]
end
return Singleton
+103
View File
@@ -0,0 +1,103 @@
local classModule = Require("components/class.lua")
local _, class = table.unpack(classModule)
local ids = Require("use/ids.lua")
local SyncObjects = {}
function GetSyncObject(syndId)
return SyncObjects[syndId]
end
function GetSyncObjects()
return SyncObjects
end
function SetSyncObject(syncId, sync)
SyncObjects[syncId] = sync
end
--- @class Sync
local Sync = class("Sync")
--- Initializes the Sync object.
function Sync:Struct()
self.syncId = ids.CreateUniqueId(SyncObjects)
self.sync = {}
self.updateWaitTime = 500
SyncObjects[self.syncId] = self
return self
end
--- Retrieves the value associated with the given key in the sync table.
--- @param key any: The key to retrieve the value for.
--- @return any: The value associated with the key.
function Sync:GetSyncKey(key)
return self.sync[key]
end
--- Called when a sync key is initialized.
--- @param key any: The key being initialized.
--- @param value any: The value being set.
function Sync:OnSyncKeyInit(key, value) end
--- Called when a sync key is updated.
--- @param key any: The key being updated.
--- @param oldValue any: The old value of the key.
--- @param newValue any: The new value of the key.
function Sync:OnSyncKeyUpdate(key, oldValue, newValue) end
--- Called when a sync key is removed.
--- @param key any: The key being removed.
function Sync:OnSyncKeyRemove(key) end
-- Server
if not IsDuplicityVersion() then goto client end
--- Sets a sync key and triggers a client event to update the sync table.
--- @param key any: The key to set.
--- @param value any: The value to set for the key.
function Sync:SetSynckey(key, value)
self.sync[key] = value
CreateThread(function()
SetTimeout(self.updateWaitTime, function()
TriggerClientEvent("Sync:Setup", -1, self.syncId, self.sync)
end)
end)
end
-- Client
if IsDuplicityVersion() then return Sync end
::client::
--- Compares the current sync table with a new table and updates accordingly.
--- @param newTable table: The new sync table to compare with.
function Sync:_CompareAndUpdate(newTable)
local oldTable = self.sync
for key, oldValue in pairs(oldTable) do
local newValue = newTable[key]
if newValue == nil then
self:OnSyncKeyRemove(key)
elseif oldValue ~= newValue then
self:OnSyncKeyUpdate(key, oldValue, newValue)
end
end
for key, newValue in pairs(newTable) do
if oldTable[key] == nil then
self:OnSyncKeyInit(key, newValue)
end
end
self.sync = newTable
end
RegisterNetEvent("Sync:Setup", function(syncId, sync)
local syncObj = GetSyncObject(syncId)
if not syncObj then
syncObj = reconstruct(Sync)
assert(syncObj, "Failed to sync: ", syncId)
syncObj.syncId = syncId
SetSyncObject(syncId, syncObj)
end
syncObj:_CompareAndUpdate(sync)
end)
return table.pack({Sync})
+59
View File
@@ -0,0 +1,59 @@
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
author 'The Order of the Sacred Framework'
description 'A bridge made for the community to use as a base for their own projects. This bridge will allow a single format to work with nearly all commonly used systems while still offering expandability.'
version '0.0.7'
shared_scripts {
'settings/sharedConfig.lua',
'use/*.lua',
'modules/utilities/shared/*.lua',
'modules/locales/*.lua',
}
server_scripts {
'@oxmysql/lib/MySQL.lua',
'settings/serverConfig.lua',
'modules/locales/shared.lua',
'modules/utilities/server/*.lua',
'modules/framework/**/server.lua',
'modules/inventory/**/server.lua',
'modules/stashes/server.lua',
'modules/phones/**/server.lua',
'modules/managment/**/server.lua',
'modules/notify/server.lua',
'init.lua',
}
client_scripts {
'settings/clientConfig.lua',
'modules/locales/shared.lua',
'modules/input/client.lua',
'modules/utilities/client/*.lua',
'modules/framework/**/client.lua',
'modules/inventory/**/client.lua',
'modules/keys/**/client.lua',
'modules/fuel/**/client.lua',
'modules/target/**/client.lua',
'modules/menu/client.lua',
'modules/notify/client.lua',
'modules/dispatch/**/client.lua',
'modules/progressbars/**/client.lua',
'modules/clothing/**/client.lua',
'modules/weather/**/client.lua',
'modules/points/*.lua',
'modules/math/*.lua',
'init.lua',
}
files {
'locales/*.json',
'components/*.lua',
}
dependencies {
'/server:6116',
'/onesync',
'ox_lib',
}
+88
View File
@@ -0,0 +1,88 @@
Bridge = {
modules = {},
}
PlayerLoaded = false
PlayerIdentifier = nil
PlayerJobName = nil
PlayerJobLabel = nil
PlayerJobGradeName = nil
PlayerJobGradeLevel = nil
Bridge.Inventory = Inventory
Bridge.Menu = Menu
Bridge.Language = Language
Bridge.Debugger = Debugger
Bridge.Framework = Framework
Bridge.Doorlock = Doorlock
Bridge.Phone = Phone
Bridge.Notify = Notify
Bridge.Vehicle = Vehicle
Bridge.Dispatch = Dispatch
Bridge.Weather = Weather
Bridge.Target = Target
Bridge.Table = Table
Bridge.Math = Math
Bridge.Clothing = Clothing
Bridge.Progressbar = Progressbar
Bridge.Helper = Helper
-- Fill the bridge tables with player data.
function FillBridgeTables()
PlayerLoaded = true
PlayerIdentifier = Framework.GetPlayerIdentifier()
PlayerJobName, PlayerJobLabel, PlayerJobGradeName, PlayerJobGradeLevel = Framework.GetPlayerJob()
end
-- Clean the bridge tables.
function ClearClientSideVariables()
PlayerLoaded = false
PlayerIdentifier = nil
PlayerJobName = nil
PlayerJobLabel = nil
PlayerJobGradeName = nil
PlayerJobGradeLevel = nil
StoredOldClothing = {}
end
CreateThread(function()
for k, v in pairs(Bridge) do
if type(v) == 'table' then
exports(k, function()
return v
end)
v.__index = function(key, value)
IndexingFallback(v, key, value)
end
else
exports(k, v)
end
end
end)
function IndexingFallback(module, k, v)
if not module[k] then
local func = Framework[k] and type(Framework[k]) == 'function' and Framework[k] or nil
return function(...)
return func(...)
end
end
return module[k]
end
OverRide = function(module, key, value)
module[key] = value
end
RegisterCompatibility = function(key, module)
module = module or {}
module.__index = IndexingFallback
module.OverRide = function(key, value)
OverRide(module, key, value)
end
Bridge[key] = module
end
exports('RegisterCompatibility', RegisterCompatibility)
exports('Bridge', function()
return Bridge
end)
+10
View File
@@ -0,0 +1,10 @@
{
"locale-unit-test": "This is a test string",
"place_object": "-- Place Object -- \n",
"place_object_place": "[E] Place \n",
"place_object_cancel": "[X] Cancel \n",
"place_object_scroll_up": "[SCROLL UP] Change Heading \n",
"place_object_scroll_down": "[SCROLL DOWN] Change Heading",
"enter_text": "Enter Text",
"no_prop_defined": "You didnt define any object to place"
}
+148
View File
@@ -0,0 +1,148 @@
if GetResourceState('esx_skin') ~= 'started' then return end
Clothing = {}
StoredOldClothing = {}
RegisterNetEvent('community_bridge:client:updateStoredClothing', function(skindata)
StoredOldClothing = skindata
end)
local clothingData = {
male = {
components = {
face = {component_id = 0, texture = 0, drawable = 2},
mask = {component_id = 1, texture = 0, drawable = 2},
hair = {component_id = 2, texture = 0, drawable = 2},
arms = {component_id = 3, texture = 0, drawable = 2},
pants = {component_id = 4, texture = 0, drawable = 22},
bag = {component_id = 5, texture = 1, drawable = 33},
shoes = {component_id = 6, texture = 1, drawable = 33},
accessory = {component_id = 7, texture = 1, drawable = 33},
shirt = {component_id = 8, texture = 1, drawable = 11},
bodyarmor = {component_id = 9, texture = 1, drawable = 33},
decals = {component_id = 10, texture = 1, drawable = 33},
jacket = {component_id = 11, texture = 2, drawable = 4},
},
props = {
hats = {prop_id = 0, texture = 2, drawable = 4},
glasses = {prop_id = 1, texture = 2, drawable = 4},
ears = {prop_id = 2, texture = 2, drawable = 4},
watches = {prop_id = 6, texture = 2, drawable = 4},
bracelets = {prop_id = 7, texture = 2, drawable = 4},
}
},
female = {
components = {
face = {component_id = 0, texture = 0, drawable = 2},
mask = {component_id = 1, texture = 0, drawable = 2},
hair = {component_id = 2, texture = 0, drawable = 2},
arms = {component_id = 3, texture = 0, drawable = 2},
pants = {component_id = 4, texture = 0, drawable = 22},
bag = {component_id = 5, texture = 1, drawable = 33},
shoes = {component_id = 6, texture = 1, drawable = 33},
accessory = {component_id = 7, texture = 1, drawable = 33},
shirt = {component_id = 8, texture = 1, drawable = 11},
bodyarmor = {component_id = 9, texture = 1, drawable = 33},
decals = {component_id = 10, texture = 1, drawable = 33},
jacket = {component_id = 11, texture = 2, drawable = 4},
},
props = {
hats = {prop_id = 0, texture = 2, drawable = 4},
glasses = {prop_id = 1, texture = 2, drawable = 4},
ears = {prop_id = 2, texture = 2, drawable = 4},
watches = {prop_id = 6, texture = 2, drawable = 4},
bracelets = {prop_id = 7, texture = 2, drawable = 4},
}
},
}
local function convertDataToFormat(characterData)
local gender = characterData.sex
local repackedClothingData = {
[gender] = {
components = {},
props = {}
}
}
local componentMap = {
tshirt_1 = 8, -- shirt
torso_1 = 11, -- jacket
decals_1 = 10, -- decals
arms = 3, -- arms
pants_1 = 4, -- pants
shoes_1 = 6, -- shoes
mask_1 = 1, -- mask
bproof_1 = 9, -- body armor
chain_1 = 7, -- accessory (could be a necklace)
bags_1 = 5, -- bag
}
for componentName, componentId in pairs(componentMap) do
if characterData[componentName] then
repackedClothingData[gender].components[componentName] = {
component_id = componentId,
texture = characterData[componentName.."_2"],
drawable = characterData[componentName.."_1"],
}
end
end
local propMap = {
{"helmet_1", 0}, -- helmet
{"glasses_1", 1}, -- glasses
{"ears_1", 2}, -- ears
{"watches_1", 6}, -- watches
{"bracelets_1", 7} -- bracelets
}
for _, prop in ipairs(propMap) do
local propName = prop[1]
local propId = prop[2]
if characterData[propName] then
repackedClothingData[gender].props[propName] = {
prop_id = propId,
texture = characterData[propName.."_2"],
drawable = characterData[propName.."_1"],
}
end
end
return repackedClothingData
end
Clothing.SetAppearance = function(clothingData)
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
clothingData = clothingData.male
clothingData.sex = 0
else
clothingData = clothingData.female
clothingData.sex = 1
end
local repackedClothingData = convertDataToFormat(clothingData)
StoredOldClothing = Clothing.GetAppearance
TriggerEvent('skinchanger:loadSkin', repackedClothingData)
return true
end
Clothing.GetAppearance = function()
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
StoredOldClothing = skin
end)
return true
end
Clothing.RestoreAppearance = function()
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
TriggerEvent('skinchanger:loadSkin', skin)
end)
return true
end
Clothing.ReloadSkin = function()
local tableCheck = Table.TableContains(StoredOldClothing, "sex")
if not tableCheck then return Clothing.RestoreAppearance() end
return TriggerEvent('skinchanger:loadSkin', StoredOldClothing)
end
+6
View File
@@ -0,0 +1,6 @@
if GetResourceState('esx_skin') ~= 'started' then return end
RegisterNetEvent("esx_skin:save", function(skin)
local src = source
TriggerClientEvent('community_bridge:client:updateStoredClothing', src, skin)
end)
@@ -0,0 +1,28 @@
if GetResourceState('fivem-appearance') ~= 'started' then return end
Clothing = {}
StoredOldClothing = {}
Clothing.SetAppearance = function(clothingData)
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
clothingData = clothingData.male
else
clothingData = clothingData.female
end
StoredOldClothing = exports['fivem-appearance']:getPedAppearance(cache.ped)
exports['fivem-appearance']:setPedAppearance(cache.ped, clothingData)
return true
end
Clothing.GetAppearance = function()
return exports['fivem-appearance']:getPedAppearance(cache.ped)
end
Clothing.RestoreAppearance = function()
return exports['fivem-appearance']:setPedAppearance(cache.ped, StoredOldClothing)
end
Clothing.ReloadSkin = function()
TriggerEvent("fivem-appearance:client:reloadSkin", true)
end
@@ -0,0 +1,45 @@
if GetResourceState('illenium-appearance') ~= 'started' then return end
Clothing = {}
StoredOldClothing = {}
Clothing.SetAppearance = function(clothingData)
local clothing = {}
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
clothingData = clothingData.male
else
clothingData = clothingData.female
end
clothing.components = exports['illenium-appearance']:getPedComponents(cache.ped)
clothing.props = exports['illenium-appearance']:getPedProps(cache.ped)
print(json.encode(clothingData, {indent = true}))
StoredOldClothing = clothing
exports['illenium-appearance']:setPedComponents(cache.ped, clothingData.components)
exports['illenium-appearance']:setPedProp(cache.ped, clothingData.props)
return true
end
Clothing.GetAppearance = function()
local clothing = {}
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
clothing = clothing.male
else
clothing = clothing.female
end
clothing.components = exports['illenium-appearance']:getPedComponents(cache.ped)
clothing.props = exports['illenium-appearance']:getPedProps(cache.ped)
return clothing
end
Clothing.RestoreAppearance = function()
exports['illenium-appearance']:setPedComponents(cache.ped, StoredOldClothing.components)
exports['illenium-appearance']:setPedProp(cache.ped, StoredOldClothing.props)
return true
end
Clothing.ReloadSkin = function()
TriggerEvent("illenium-appearance:client:reloadSkin", true)
end
+80
View File
@@ -0,0 +1,80 @@
if GetResourceState('qb-clothing') ~= 'started' then return end
Clothing = {}
StoredOldClothing = {}
RegisterNetEvent('community_bridge:client:updateStoredClothing', function(skindata)
StoredOldClothing = skindata
end)
Clothing.SetAppearance = function(clothingData)
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
clothingData = clothingData.male
else
clothingData = clothingData.female
end
local repackedTable = {}
StoredOldClothing = Clothing.GetAppearance
local componentMap = {
[1] = 'mask',
[3] = 'arms',
[4] = 'pants',
[5] = 'bag',
[6] = 'shoes',
[7] = 'accessory',
[8] = 't-shirt',
[9] = 'vest',
[10] = 'decals',
[11] = 'torso2'
}
local propMap = {
[0] = 'hat',
[1] = 'glass',
[2] = 'ear',
[6] = 'watch',
[7] = 'bracelet'
}
local specialMap = {
eye_color_id = 'eye_color',
moles_id = 'moles',
ageing_id = 'ageing',
hair_id = 'hair',
face_id = 'face'
}
for _, data in pairs(clothingData) do
if componentMap[data.component_id] then
repackedTable[componentMap[data.component_id]] = {drawable = data.drawable, texture = data.texture}
elseif propMap[data.prop_id] then
repackedTable[propMap[data.prop_id]] = {drawable = data.drawable, texture = data.texture}
elseif specialMap[data.eye_color_id] then
repackedTable[specialMap[data.eye_color_id]] = {drawable = data.drawable, texture = data.texture}
elseif specialMap[data.moles_id] then
repackedTable[specialMap[data.moles_id]] = {drawable = data.drawable, texture = data.texture}
elseif specialMap[data.ageing_id] then
repackedTable[specialMap[data.ageing_id]] = {drawable = data.drawable, texture = data.texture}
elseif specialMap[data.hair_id] then
repackedTable[specialMap[data.hair_id]] = {drawable = data.drawable, texture = data.texture}
elseif specialMap[data.face_id] then
repackedTable[specialMap[data.face_id]] = {drawable = data.drawable, texture = data.texture}
end
end
TriggerEvent('qb-clothing:client:loadOutfit', repackedTable)
return true
end
Clothing.GetAppearance = function()
StoredOldClothing = Utility.GetEntitySkinData(cache.ped)
return Utility.GetEntitySkinData(cache.ped)
end
Clothing.RestoreAppearance = function()
return Utility.SetEntitySkinData(cache.ped, StoredOldClothing)
end
Clothing.ReloadSkin = function()
return exports['qb-clothing']:reloadSkin(GetEntityHealth(cache.ped))
end
+8
View File
@@ -0,0 +1,8 @@
if GetResourceState('qb-clothing') ~= 'started' then return end
RegisterServerEvent('qb-clothing:saveSkin', function(model, skin)
local src = source
if model ~= nil and skin ~= nil then
TriggerClientEvent('community_bridge:client:updateStoredClothing', src, skin)
end
end)
+18
View File
@@ -0,0 +1,18 @@
if GetResourceState('cd_dispatch') ~= 'started' then return end
Dispatch = {}
Dispatch.SendAlert = function(data)
local playerData = exports['cd_dispatch']:GetPlayerInfo()
local randomID = Bridge.helper.RandomString()
TriggerServerEvent('cd_dispatch:AddNotification', {
job_table = data.job,
coords = data.coords or playerData.coords,
title = data.code or '10-80',
message = data.message,
flash = 0,
unique_id = randomID,
sound = 1,
blip = { sprite = 431, scale = 1.2, colour = 3, flashes = false, text = data.message, time = 10000, radius = 0, }
})
end
@@ -0,0 +1,21 @@
if GetResourceState('linden_outlawalert') ~= 'started' then return end
Dispatch = {}
Dispatch.SendAlert = function(data)
local formattedData = {
displayCode = data.code or '10-80',
description = data.message,
isImportant = data.priority or 0,
recipientList = data.job,
length = '10000',
infoM = data.icon or 'fas fa-question',
info = data.message
}
local dispatchData = {
dispatchData = formattedData,
caller = 'Anonymous',
coords = GetEntityCoords(cache.ped)
}
TriggerServerEvent('wf-alerts:svNotify', dispatchData)
end
+75
View File
@@ -0,0 +1,75 @@
if GetResourceState('ps-dispatch') ~= 'started' then return end
Dispatch = {}
Dispatch.SendAlert = function(data)
local customData = {
message = data.message,
code = data.code or '10-80',
icon = data.icon or 'fas fa-question',
priority = data.priority or 2,
coords = data.coords or vec3(0.0, 0.0, 0.0),
gender = data.gender or nil,
camId = data.camId or nil,
color = data.firstColor or nil,
callsign = data.callsign or nil,
name = data.name or nil,
vehicle = data.model or nil,
plate = data.plate or nil,
alertTime = data.alertTime or nil,
doorCount = data.doorCount or nil,
automaticGunfire = data.automaticGunfire or false,
alert = {
radius = data.radius or 0,
recipientList = data.job or { 'leo' },
sprite = data.sprite or 1,
color = data.color or 1,
scale = data.scale or 0.5,
length = data.length or 2,
sound = data.sound or "Lose_1st",
sound2 = data.sound2 or "GTAO_FM_Events_Soundset",
offset = data.offset or false,
flash = data.flash or false
},
jobs = { data.job or 'leo' }
}
exports["ps-dispatch"]:CustomAlert(customData)
end
--[[
-- tested, it worked
CreateThread(function()
local data = {
message = "Fart",
code = '10-80',
icon = 'fas fa-question',
priority = 2,
coords = vec3(0.0, 0.0, 0.0),
gender = nil,
camId = nil,
color = nil,
callsign = nil,
name = "Test Name",
vehicle = nil,
plate = nil,
alertTime = 30000,
doorCount = nil,
automaticGunfire = false,
alert = {
radius = 0,
recipientList = { 'leo' },
sprite = 1,
color = 1,
scale = 0.5,
length = 2,
sound = "Lose_1st",
sound2 = "GTAO_FM_Events_Soundset",
offset = false,
flash = false
},
jobs = { 'leo' }
}
Dispatch.SendAlert(data)
print("Dispatched")
end)
--]]
@@ -0,0 +1,16 @@
if GetResourceState('rcore_dispatch') ~= 'started' then return end
Dispatch = {}
Dispatch.SendAlert = function(data)
local playerData = exports['rcore_dispatch']:GetPlayerData()
TriggerEvent('rcore_dispatch:server:sendAlert', {
code = data.code or '10-80',
default_priority = 'low',
coords = data.coords or playerData.coords,
job = data.job,
text = data.message or 'No message provided',
type = 'alerts',
blip = { sprite = 54, colour = 3, scale = 0.7, text = data.message or "No Message", flashes = false, radius = 0 }
})
end
@@ -0,0 +1,7 @@
if GetResourceState('doors_creator') ~= 'started' then return end
Doorlock = {}
Doorlock.GetClosestDoor = function()
return exports["doors_creator"]:getClosestActiveDoor()
end
@@ -0,0 +1,13 @@
if GetResourceState('doors_creator') ~= 'started' then return end
Doorlock = {}
Doorlock.ToggleDoorLock = function(doorID, toggle)
local state = toggle
if state then
exports["doors_creator"]:setDoorState(doorID, 1)
else
exports["doors_creator"]:setDoorState(doorID, 0)
end
return true
end
+7
View File
@@ -0,0 +1,7 @@
if GetResourceState('ox_doorlock') ~= 'started' then return end
Doorlock = {}
Doorlock.GetClosestDoor = function()
return exports.ox_doorlock:getClosestDoor()
end
+13
View File
@@ -0,0 +1,13 @@
if GetResourceState('ox_doorlock') ~= 'started' then return end
Doorlock = {}
Doorlock.ToggleDoorLock = function(doorID, toggle)
local state = toggle
if state then
exports.ox_doorlock:setDoorState(doorID, 1)
else
exports.ox_doorlock:setDoorState(doorID, 0)
end
return true
end
+20
View File
@@ -0,0 +1,20 @@
if GetResourceState('qb-doorlock') ~= 'started' then return end
Doorlock = {}
Doorlock.GetClosestDoor = function()
local closestDoor = exports["qb-doorlock"]:GetClosestDoor()
if Table.CheckPopulated(closestDoor) then return closestDoor end
local allDoors = exports["qb-doorlock"]:GetDoorList()
local pedCoords = GetEntityCoords(cache.ped)
local door = 0
local doorDist = 1000.0
for doorID, data in pairs(allDoors) do
local dist = #(pedCoords - data.objCoords)
if dist < doorDist then
door = doorID
doorDist = dist
end
end
return door
end
+8
View File
@@ -0,0 +1,8 @@
if GetResourceState('qb-doorlock') ~= 'started' then return end
Doorlock = {}
Doorlock.ToggleDoorLock = function(doorID, toggle)
TriggerClientEvent('qb-doorlock:client:setState', -1, 0, doorID, toggle, false, false, false)
return true
end
@@ -0,0 +1,18 @@
if GetResourceState('rcore_doorlock') ~= 'started' then return end
Doorlock = {}
Doorlock.GetClosestDoor = function()
local allDoors = exports.rcore_doorlock:getLoadedDoors()
local pedCoords = GetEntityCoords(cache.ped)
local door = 0
local doorDist = 1000.0
for _, data in pairs(allDoors) do
local dist = #(pedCoords - data.coords)
if dist < doorDist then
door = data.id
doorDist = dist
end
end
return door
end
@@ -0,0 +1,13 @@
if GetResourceState('rcore_doorlock') ~= 'started' then return end
Doorlock = {}
Doorlock.ToggleDoorLock = function(doorID, toggle)
local state = toggle
if state then
exports.rcore_doorlock:changeDoorState(doorID, 0)
else
exports.rcore_doorlock:changeDoorState(doorID, 1)
end
return true
end
+54
View File
@@ -0,0 +1,54 @@
if GetResourceState('es_extended') ~= 'started' then return end
ESX = exports["es_extended"]:getSharedObject()
Framework = {}
Framework.GetPlayerData = function()
return ESX.PlayerData
end
Framework.GetPlayerMetaData = function(metadata)
return ESX.GetPlayerData().metadata[metadata]
end
Framework.GetPlayerIdentifier = function()
return ESX.GetPlayerData().identifier
end
Framework.GetPlayerName = function()
local playerData = ESX.GetPlayerData()
return playerData.firstName, playerData.lastName
end
Framework.GetPlayerJob = function()
local playerData = ESX.GetPlayerData()
return playerData.job.name, playerData.job.label, playerData.job.grade_label, playerData.job.grade
end
Framework.GetPlayerInventory = function()
return ESX.GetPlayerData().inventory
end
Framework.GetIsPlayerDead = function()
return ESX.GetPlayerData().dead
end
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
Wait(1500)
FillBridgeTables()
TriggerEvent('community_bridge:Client:OnPlayerLoaded')
end)
RegisterNetEvent('esx:onPlayerLogout', function()
ClearClientSideVariables()
TriggerEvent('community_bridge:Client:OnPlayerUnload')
end)
RegisterNetEvent('esx:setJob', function(data)
PlayerJobName = data.name
PlayerJobLabel = data.label
PlayerJobGradeName = data.grade_label
PlayerJobGradeLevel = data.grade
TriggerEvent('community_bridge:Client:OnPlayerJobUpdate',PlayerJobName, PlayerJobLabel, PlayerJobGradeName, PlayerJobGradeLevel)
end)
+196
View File
@@ -0,0 +1,196 @@
if GetResourceState('es_extended') ~= 'started' then return end
ESX = exports["es_extended"]:getSharedObject()
Framework = {}
-- Framework.GetPlayerIdentifier(src)
-- Returns the citizen ID of the player.
Framework.GetPlayerIdentifier = function(src)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.getIdentifier()
end
-- Framework.GetPlayerName(src)
-- Returns the first and last name of the player.
Framework.GetPlayerName = function(src)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.variables.firstName, xPlayer.variables.lastName
end
-- Framework.GetItem(src, item, metadata)
-- Returns a table of items matching the specified name and if passed metadata from the player's inventory.
-- returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot}
Framework.GetItem = function(src, item, _)
local playerItems = ESX.GetPlayerFromId(src).getInventory()
local repackedTable = {}
for _, v in pairs(playerItems) do
if v.name == item then
table.insert(repackedTable, {
name = v.name,
count = v.count,
--metadata = v.metadata,
--slot = v.slot,
})
end
end
return repackedTable
end
-- Framework.GetItemCount(src, item, _)
-- Returns the count of items matching the specified name and if passed metadata from the player's inventory.
Framework.GetItemCount = function(src, item, _)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.getInventoryItem(item).count
end
-- Framework.GetPlayerInventory(src)
-- Returns the entire inventory of the player as a table.
-- returns {name = v.name, count = v.amount, _, _}
Framework.GetPlayerInventory = function(src)
local playerItems = ESX.GetPlayerFromId(src).getInventory()
local repackedTable = {}
for _, v in pairs(playerItems) do
if v.count > 0 then
table.insert(repackedTable, {
name = v.name,
count = v.count,
--metadata = v.metadata,
--slot = v.slot,
})
end
end
return repackedTable
end
-- Framework.SetMetadata(src, metadata, value)
-- Adds the specified metadata key and number value to the player's data.
Framework.SetPlayerMetadata = function(src, metadata, value)
local xPlayer = ESX.GetPlayerFromId(src)
xPlayer.setMeta(metadata, value, nil)
return true
end
-- Framework.GetMetadata(src, metadata)
-- Gets the specified metadata key and value to the player's data.
Framework.GetPlayerMetadata = function(src, metadata)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.getMeta(metadata) or false
end
-- defualt esx Available tables are
-- identifier, accounts, group, inventory, job, job_grade, loadout,
-- metadata, position, firstname, lastname, dateofbirth, sex, height,
-- skin, status, is_dead, id, disabled, last_property, created_at, last_seen,
-- phone_number, pincode
Framework.GetStatus = function(src, column)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.get(column) or nil
end
-- Framework.AddThirst(src, value)
-- Adds the specified value from the player's thirst level.
Framework.AddThirst = function(src, value)
local clampIT = Math.Clamp(value, 0, 200000)
local levelForEsx = clampIT * 2000
TriggerClientEvent('esx_status:add', src, 'thirst', levelForEsx)
return levelForEsx
end
-- Framework.AddHunger(src, value)
-- Adds the specified value from the player's hunger level.
Framework.AddHunger = function(src, value)
local clampIT = Math.Clamp(value, 0, 200000)
local levelForEsx = clampIT * 2000
TriggerClientEvent('esx_status:add', src, 'hunger', levelForEsx)
return levelForEsx
end
Framework.GetHunger = function(src)
local status = Framework.GetStatus(src, "status")
if not status then return 0 end
return status.hunger
end
Framework.GetThirst = function(src)
local status = Framework.GetStatus(src, "status")
if not status then return 0 end
return status.thirst
end
-- Framework.GetPlayerPhone(src)
-- Returns the phone number of the player.
Framework.GetPlayerPhone = function(src)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.get("phone_number")
end
-- Framework.GetPlayerJob(src)
-- Returns the job name, label, grade name, and grade level of the player.
Framework.GetPlayerJob = function(src)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.getJob().name, xPlayer.getJob().label, xPlayer.getJob().grade_label, xPlayer.getJob().grade
end
-- Framework.GetPlayersByJob(jobname)
-- returns a table of player sources that have the specified job name.
Framework.GetPlayersByJob = function(job)
local players = GetPlayers()
local playerList = {}
for _, src in pairs(players) do
local xPlayer = ESX.GetPlayerFromId(src)
if xPlayer.getJob().name == job then
table.insert(playerList, src)
end
end
return playerList
end
-- Framework.SetPlayerJob(src, name, grade)
-- Sets the player's job to the specified name and grade.
Framework.SetPlayerJob = function(src, name, grade)
local xPlayer = ESX.GetPlayerFromId(src)
if not ESX.DoesJobExist(name, grade) then lib.print.error("Job Does Not Exsist In Framework :NAME "..name.." Grade:"..grade) return end
return xPlayer.setJob(name, grade)
end
-- Framework.AddAccountBalance(src, _type, amount)
-- Adds the specified amount to the player's account balance of the specified type.
Framework.AddAccountBalance = function(src, _type, amount)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.addAccountMoney(_type, amount)
end
-- Framework.RemoveAccountBalance(src, _type, amount)
-- Removes the specified amount from the player's account balance of the specified type.
Framework.RemoveAccountBalance = function(src, _type, amount)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.removeAccountMoney(_type, amount)
end
-- Framework.GetAccountBalance(src, _type)
-- Returns the player's account balance of the specified type.
Framework.GetAccountBalance = function(src, _type)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.getAccount(_type).money
end
-- Framework.AddItem(src, item, amount, _, _)
-- Adds the specified item to the player's inventory.
Framework.AddItem = function(src, item, amount, slot, metadata)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.addInventoryItem(item, amount)
end
-- Framework.RemoveItem(src, item, amount, _, _)
-- Removes the specified item from the player's inventory.
Framework.RemoveItem = function(src, item, amount, slot, metadata)
local xPlayer = ESX.GetPlayerFromId(src)
return xPlayer.removeInventoryItem(item, amount)
end
-- Framework.RegisterUsableItem(item, cb)
-- Registers a usable item with a callback function.
Framework.RegisterUsableItem = function(item, cb)
ESX.RegisterUsableItem(item, cb)
end
+1
View File
@@ -0,0 +1 @@
if GetResourceState('ox_core') ~= 'started' then return end
+1
View File
@@ -0,0 +1 @@
if GetResourceState('ox_core') ~= 'started' then return end
+71
View File
@@ -0,0 +1,71 @@
if GetResourceState('qb-core') ~= 'started' then return end
if GetResourceState('qbx_core') == 'started' then return end
QBCore = exports['qb-core']:GetCoreObject()
Framework = {}
Framework.GetPlayerData = function()
return QBCore.Functions.GetPlayerData()
end
Framework.GetPlayerMetaData = function(metadata)
return QBCore.Functions.GetPlayerData().metadata[metadata]
end
Framework.GetItemInfo = function(item)
local itemData = QBCore.Shared.Items[item]
if not itemData then return {} end
local repackedTable = {
name = itemData.name,
label = itemData.label,
stack = itemData.unique,
weight = itemData.weight,
description = itemData.description,
image = itemData.image
}
return repackedTable
end
Framework.GetPlayerIdentifier = function()
return QBCore.Functions.GetPlayerData().citizenid
end
Framework.GetPlayerName = function()
local playerData = QBCore.Functions.GetPlayerData()
return playerData.charinfo.firstname, playerData.charinfo.lastname
end
Framework.GetPlayerJob = function()
local playerData = QBCore.Functions.GetPlayerData()
return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level
end
Framework.GetPlayerInventory = function()
return QBCore.Functions.GetPlayerData().items
end
Framework.GetIsPlayerDead = function()
return QBCore.Functions.GetPlayerData().metadata["isdead"] or QBCore.GetPlayerData().metadata["inlaststand"]
end
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
Wait(1500)
FillBridgeTables()
TriggerEvent('community_bridge:Client:OnPlayerLoaded')
end)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
ClearClientSideVariables()
TriggerEvent('community_bridge:Client:OnPlayerUnload')
end)
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(data)
PlayerJobName = data.name
PlayerJobLabel = data.label
PlayerJobGradeName = data.grade.name
PlayerJobGradeLevel = data.grade.level
TriggerEvent('community_bridge:Client:OnPlayerJobUpdate',PlayerJobName, PlayerJobLabel, PlayerJobGradeName, PlayerJobGradeLevel)
end)
Bridge.RegisterModule("Framework", Framework)
+247
View File
@@ -0,0 +1,247 @@
if GetResourceState('qb-core') ~= 'started' then return end
if GetResourceState('qbx_core') == 'started' then return end
QBCore = exports['qb-core']:GetCoreObject()
Framework = {}
-- Framework.GetPlayerIdentifier(src)
-- Returns the citizen ID of the player.
Framework.GetPlayerIdentifier = function(src)
return QBCore.Functions.GetPlayer(src).PlayerData.citizenid
end
-- Framework.GetPlayerName(src)
-- Returns the first and last name of the player.
Framework.GetPlayerName = function(src)
local playerData = QBCore.Functions.GetPlayer(src).PlayerData
return playerData.charinfo.firstname, playerData.charinfo.lastname
end
-- Framework.GetItem(src, item, metadata)
-- Returns a table of items matching the specified name and if passed metadata from the player's inventory.
-- returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot}
Framework.GetItem = function(src, item, metadata)
local playerInventory = QBCore.Functions.GetPlayer(src).PlayerData.items
local repackedTable = {}
for _, v in pairs(playerInventory) do
if v.name == item and (not metadata or v.info == metadata) then
table.insert(repackedTable, {
name = v.name,
count = v.amount,
metadata = v.info,
slot = v.slot,
})
end
end
return repackedTable
end
-- Framework.GetItemCount(src, item, metadata)
-- Returns the count of items matching the specified name and if passed metadata from the player's inventory.
Framework.GetItemCount = function(src, item, metadata)
local playerInventory = QBCore.Functions.GetPlayer(src).PlayerData.items
local count = 0
for _, v in pairs(playerInventory) do
if v.name == item and (not metadata or v.info == metadata) then
count = count + v.amount
end
end
return count
end
-- Framework.GetPlayerInventory(src)
-- Returns the entire inventory of the player as a table.
-- returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot}
Framework.GetPlayerInventory = function(src)
local playerItems = QBCore.Functions.GetPlayer(src).PlayerData.items
local repackedTable = {}
for _, v in pairs(playerItems) do
table.insert(repackedTable, {
name = v.name,
count = v.amount,
metadata = v.info,
slot = v.slot,
})
end
return repackedTable
end
-- Framework.SetMetadata(src, metadata, value)
-- Adds the specified metadata key and number value to the player's data.
Framework.SetPlayerMetadata = function(src, metadata, value)
local player = QBCore.Functions.GetPlayer(src)
player.Functions.SetMetaData(metadata, value)
return true
end
-- Framework.GetMetadata(src, metadata)
-- Gets the specified metadata key to the player's data.
Framework.GetPlayerMetadata = function(src, metadata)
local player = QBCore.Functions.GetPlayer(src)
local playerData = player.PlayerData
return playerData.metadata[metadata] or false
end
-- Framework.AddStress(src, value)
-- Adds the specified value to the player's stress level and updates the client HUD.
Framework.AddStress = function(src, value)
local player = QBCore.Functions.GetPlayer(src)
local playerData = player.PlayerData
local newStress = playerData.metadata.stress + value
player.Functions.SetMetaData('stress', Math.Clamp(newStress, 0, 100))
TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newStress
end
-- Framework.RemoveStress(src, value)
-- Removes the specified value from the player's stress level and updates the client HUD.
Framework.RemoveStress = function(src, value)
local player = QBCore.Functions.GetPlayer(src)
local playerData = player.PlayerData
local newStress = (playerData.metadata.stress or 0) - value
player.Functions.SetMetaData('stress', Math.Clamp(newStress, 0, 100))
TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newStress
end
-- Framework.AddHunger(src, value)
-- Adds the specified value from the player's hunger level.
Framework.AddHunger = function(src, value)
local player = QBCore.Functions.GetPlayer(src)
local playerData = player.PlayerData
local newHunger = (playerData.metadata.hunger or 0) + value
player.Functions.SetMetaData('hunger', Math.Clamp(newHunger, 0, 100))
--TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newHunger
end
-- Framework.AddThirst(src, value)
-- Adds the specified value from the player's thirst level.
Framework.AddThirst = function(src, value)
local player = QBCore.Functions.GetPlayer(src)
local playerData = player.PlayerData
local newThirst = (playerData.metadata.thirst or 0) + value
player.Functions.SetMetaData('thirst', Math.Clamp(newThirst, 0, 100))
--TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newThirst
end
Framework.GetHunger = function(src)
local player = QBCore.Functions.GetPlayer(src)
local playerData = player.PlayerData
local newHunger = (playerData.metadata.hunger or 0)
return newHunger
end
Framework.GetThirst = function(src)
local player = QBCore.Functions.GetPlayer(src).PlayerData
local newThirst = (player.metadata.thirst or 0)
return newThirst
end
-- Framework.GetPlayerPhone(src)
-- Returns the phone number of the player.
Framework.GetPlayerPhone = function(src)
local playerData = QBCore.Functions.GetPlayer(src).PlayerData
return playerData.charinfo.phone
end
-- Framework.GetPlayerGang(src)
-- Returns the gang name of the player.
Framework.GetPlayerGang = function(src)
local player = QBCore.Functions.GetPlayer(src).PlayerData
return player.gang.name
end
-- Framework.GetPlayersByJob(jobname)
-- returns a table of player sources that have the specified job name.
Framework.GetPlayersByJob = function(job)
local players = QBCore.Functions.GetPlayers()
local playerList = {}
for _, src in pairs(players) do
local player = QBCore.Functions.GetPlayer(src).PlayerData
if player.job.name == job then
table.insert(playerList, src)
end
end
return playerList
end
-- Framework.GetPlayerJob(src)
-- Returns the job name, label, grade name, and grade level of the player.
Framework.GetPlayerJob = function(src)
local player = QBCore.Functions.GetPlayer(src).PlayerData
return player.job.name, player.job.label, player.job.grade.name, player.job.grade.level
end
-- Framework.SetPlayerJob(src, name, grade)
-- Sets the player's job to the specified name and grade.
Framework.SetPlayerJob = function(src, name, grade)
local player = QBCore.Functions.GetPlayer(src)
return player.Functions.SetJob(name, grade)
end
-- Framework.AddAccountBalance(src, _type, amount)
-- Adds the specified amount to the player's account balance of the specified type.
Framework.AddAccountBalance = function(src, _type, amount)
local player = QBCore.Functions.GetPlayer(src)
if _type == 'money' then _type = 'cash' end
return player.Functions.AddMoney(_type, amount)
end
-- Framework.RemoveAccountBalance(src, _type, amount)
-- Removes the specified amount from the player's account balance of the specified type.
Framework.RemoveAccountBalance = function(src, _type, amount)
local player = QBCore.Functions.GetPlayer(src)
if _type == 'money' then _type = 'cash' end
return player.Functions.RemoveMoney(_type, amount)
end
-- Framework.GetAccountBalance(src, _type)
-- Returns the player's account balance of the specified type.
Framework.GetAccountBalance = function(src, _type)
local playerData = QBCore.Functions.GetPlayer(src).PlayerData
if _type == 'money' then _type = 'cash' end
return playerData.money[_type]
end
-- Framework.AddItem(src, item, amount, slot, metadata)
-- Adds the specified item to the player's inventory.
Framework.AddItem = function(src, item, amount, slot, metadata)
local player = QBCore.Functions.GetPlayer(src)
return player.Functions.AddItem(item, amount, slot, metadata)
end
-- Framework.RemoveItem(src, item, amount, slot, metadata)
-- Removes the specified item from the player's inventory.
Framework.RemoveItem = function(src, item, amount, slot, metadata)
local player = QBCore.Functions.GetPlayer(src)
return player.Functions.RemoveItem(item, amount, slot or nil)
end
-- Framework.SetMetadata(src, item, slot, metadata)
-- Sets the metadata for the specified item in the player's inventory.
-- Notes, this is kinda a jank workaround. with the framework aside from updating the entire table theres not really a better way
Framework.SetMetadata = function(src, item, slot, metadata)
local player = QBCore.Functions.GetPlayer(src)
local slotFinder = Framework.GetPlayerInventory(src)
local freeSlot = Table.FindFirstUnoccupiedSlot(slotFinder)
local itemSlot = slot or nil
if itemSlot == nil then
for _, v in pairs(slotFinder) do
if v.name == item then
slot = v.slot
break
end
end
end
player.Functions.RemoveItem(item, 1, itemSlot)
return player.Functions.AddItem(item, 1, freeSlot, metadata)
end
-- Framework.RegisterUsableItem(item, cb)
-- Registers a usable item with a callback function.
Framework.RegisterUsableItem = function(item, cb)
QBCore.Functions.CreateUseableItem(item, cb)
end
+65
View File
@@ -0,0 +1,65 @@
if GetResourceState('qbx_core') ~= 'started' then return end
-- This fork is a cult, they just belittle people and degrade them to feel better about themselves.
-- Defualt support for the best free inventory currently available is cool though.
QBox = exports.qbx_core
Framework = {}
Framework.GetPlayerData = function()
return QBox.GetPlayerData()
end
Framework.GetPlayerMetaData = function(metadata)
local playerData = QBox.GetPlayerData()
return playerData.metadata[metadata]
end
Framework.GetPlayerIdentifier = function()
return QBox.GetPlayerData().citizenid
end
Framework.GetPlayerName = function()
local playerData = QBox.GetPlayerData()
return playerData.charinfo.firstname, playerData.charinfo.lastname
end
Framework.GetPlayerJob = function()
local playerData = QBox.GetPlayerData()
return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level
end
Framework.GetPlayerInventory = function()
return QBox.GetPlayerData().items
end
Framework.GetIsPlayerDead = function()
return QBox.GetPlayerData().metadata["isdead"] or QBox.GetPlayerData().metadata["inlaststand"]
end
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
Wait(1500)
FillBridgeTables()
TriggerEvent('community_bridge:Client:OnPlayerLoaded')
end)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
ClearClientSideVariables()
TriggerEvent('community_bridge:Client:OnPlayerUnload')
end)
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(data)
PlayerJobName = data.name
PlayerJobLabel = data.label
PlayerJobGradeName = data.grade.name
PlayerJobGradeLevel = data.grade.level
TriggerEvent('community_bridge:Client:OnPlayerJobUpdate',PlayerJobName, PlayerJobLabel, PlayerJobGradeName, PlayerJobGradeLevel)
end)
--[[
print("Qbox shit.")
print(Framework.GetPlayerIdentifier())
print(json.encode(Framework.GetPlayerInventory()))
print(json.encode(Framework.GetIsPlayerDead()))
--]]
+238
View File
@@ -0,0 +1,238 @@
if GetResourceState('qbx_core') ~= 'started' then return end
-- This fork is a cult, they just belittle people and degrade them to feel better about themselves.
-- Defualt support for the best free inventory currently available is cool though.
local QBox = exports.qbx_core
Framework = {}
-- Framework.GetPlayerIdentifier(src)
-- Returns the citizen ID of the player.
Framework.GetPlayerIdentifier = function(src)
local playerData = QBox:GetPlayer(src).PlayerData
if not playerData then return false end
return playerData.citizenid
end
-- Framework.GetPlayerName(src)
-- Returns the first and last name of the player.
Framework.GetPlayerName = function(src)
local playerData = QBox:GetPlayer(src).PlayerData
return playerData.charinfo.firstname, playerData.charinfo.lastname
end
-- Framework.GetItem(src, item, metadata)
-- Returns a table of items matching the specified name and if passed metadata from the player's inventory.
-- returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot}
Framework.GetItem = function(src, item, metadata)
local playerInventory = QBox:GetPlayer(src).PlayerData.items
local repackedTable = {}
for _, v in pairs(playerInventory) do
if v.name == item and (not metadata or v.info == metadata) then
table.insert(repackedTable, {
name = v.name,
count = v.amount,
metadata = v.info,
slot = v.slot,
})
end
end
return repackedTable
end
-- Framework.GetItemCount(src, item, metadata)
-- Returns the count of items matching the specified name and if passed metadata from the player's inventory.
Framework.GetItemCount = function(src, item, metadata)
local playerInventory = QBox:GetPlayer(src).PlayerData.items
local count = 0
for _, v in pairs(playerInventory) do
if v.name == item and (not metadata or v.info == metadata) then
count = count + v.amount
end
end
return count
end
-- Framework.GetPlayerInventory(src)
-- Returns the entire inventory of the player as a table.
-- returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot}
Framework.GetPlayerInventory = function(src)
local playerItems = QBox:GetPlayer(src).PlayerData.items
local repackedTable = {}
for _, v in pairs(playerItems) do
table.insert(repackedTable, {
name = v.name,
count = v.amount,
metadata = v.metadata,
slot = v.slot,
})
end
return repackedTable
end
-- Framework.SetMetadata(src, metadata, value)
-- Adds the specified metadata key and number value to the player's data.
Framework.SetPlayerMetadata = function(src, metadata, value)
local player = QBox:GetPlayer(src)
player.Functions.SetMetaData(metadata, value)
return true
end
-- Framework.GetMetadata(src, metadata)
-- Gets the specified metadata key to the player's data.
Framework.GetPlayerMetadata = function(src, metadata)
local player = QBox:GetPlayer(src)
local playerData = player.PlayerData
return playerData.metadata[metadata] or false
end
-- Framework.AddStress(src, value)
-- Adds the specified value to the player's stress level and updates the client HUD.
Framework.AddStress = function(src, value)
local player = QBox:GetPlayer(src)
local playerData = player.PlayerData
local newStress = playerData.metadata.stress + value
player.Functions.SetMetaData('stress', Math.Clamp(newStress, 0, 100))
TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newStress
end
-- Framework.RemoveStress(src, value)
-- Removes the specified value from the player's stress level and updates the client HUD.
Framework.RemoveStress = function(src, value)
local player = QBox:GetPlayer(src)
local playerData = player.PlayerData
local newStress = (playerData.metadata.stress or 0) - value
player.Functions.SetMetaData('stress', Math.Clamp(newStress, 0, 100))
TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newStress
end
-- Framework.AddHunger(src, value)
-- Adds the specified value from the player's hunger level.
Framework.AddHunger = function(src, value)
local player = QBox:GetPlayer(src)
local playerData = player.PlayerData
local newHunger = (playerData.metadata.hunger or 0) + value
player.Functions.SetMetaData('hunger', Math.Clamp(newHunger, 0, 100))
--TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newHunger
end
-- Framework.AddThirst(src, value)
-- Adds the specified value from the player's thirst level.
Framework.AddThirst = function(src, value)
local player = QBox:GetPlayer(src)
local playerData = player.PlayerData
local newThirst = (playerData.metadata.thirst or 0) + value
player.Functions.SetMetaData('thirst', Math.Clamp(newThirst, 0, 100))
--TriggerClientEvent('hud:client:UpdateStress', src, newStress)
return newThirst
end
Framework.GetHunger = function(src)
local player = QBox:GetPlayer(src)
local playerData = player.PlayerData
local newHunger = (playerData.metadata.hunger or 0)
return newHunger
end
Framework.GetThirst = function(src)
local player = QBox:GetPlayer(src)
local playerData = player.PlayerData
local newThirst = (playerData.metadata.thirst or 0)
return newThirst
end
-- Framework.GetPlayerPhone(src)
-- Returns the phone number of the player.
Framework.GetPlayerPhone = function(src)
local playerData = QBox:GetPlayer(src).PlayerData
return playerData.charinfo.phone
end
-- Framework.GetPlayerGang(src)
-- Returns the gang name of the player.
Framework.GetPlayerGang = function(src)
local player = QBox:GetPlayer(src).PlayerData
return player.gang.name
end
Framework.GetPlayersByJob = function(job)
local playerList = {}
local players = QBox:GetQBPlayers()
for src, player in pairs(players) do
if player.PlayerData.job.name == job then
table.insert(playerList, src)
end
end
return playerList
end
-- Framework.GetPlayerJob(src)
-- Returns the job name, label, grade name, and grade level of the player.
Framework.GetPlayerJob = function(src)
local player = QBox:GetPlayer(src).PlayerData
return player.job.name, player.job.label, player.job.grade.name, player.job.grade.level
end
-- Framework.SetPlayerJob(src, name, grade)
-- Sets the player's job to the specified name and grade.
Framework.SetPlayerJob = function(src, name, grade)
local player = QBox:GetPlayer(src)
return player.Functions.SetJob(name, grade)
end
-- Framework.AddAccountBalance(src, _type, amount)
-- Adds the specified amount to the player's account balance of the specified type.
Framework.AddAccountBalance = function(src, _type, amount)
local player = QBox:GetPlayer(src)
if _type == 'money' then _type = 'cash' end
return player.Functions.AddMoney(_type, amount)
end
-- Framework.RemoveAccountBalance(src, _type, amount)
-- Removes the specified amount from the player's account balance of the specified type.
Framework.RemoveAccountBalance = function(src, _type, amount)
local player = QBox:GetPlayer(src)
if _type == 'money' then _type = 'cash' end
return player.Functions.RemoveMoney(_type, amount)
end
-- Framework.GetAccountBalance(src, _type)
-- Returns the player's account balance of the specified type.
Framework.GetAccountBalance = function(src, _type)
local playerData = QBox:GetPlayer(src).PlayerData
if _type == 'money' then _type = 'cash' end
return playerData.money[_type]
end
-- Framework.AddItem(src, item, amount, slot, metadata)
-- Adds the specified item to the player's inventory.
Framework.AddItem = function(src, item, amount, slot, metadata)
local player = QBox:GetPlayer(src)
return player.Functions.AddItem(item, amount, slot, metadata)
end
-- Framework.RemoveItem(src, item, amount, slot, metadata)
-- Removes the specified item from the player's inventory.
Framework.RemoveItem = function(src, item, amount, slot, metadata)
local player = QBox:GetPlayer(src)
return player.Functions.RemoveItem(item, amount, slot)
end
-- Framework.SetMetadata(src, item, slot, metadata)
-- Sets the metadata for the specified item in the player's inventory.
-- Notes, this is kinda a jank workaround. with the framework aside from updating the entire table theres not really a better way
Framework.SetMetadata = function(src, item, slot, metadata)
local player = QBox:GetPlayer(src)
player.Functions.RemoveItem(item, 1, slot)
return player.Functions.AddItem(item, 1, slot, metadata)
end
-- Framework.RegisterUsableItem(item, cb)
-- Registers a usable item with a callback function.
Framework.RegisterUsableItem = function(item, cb)
return QBox:CreateUseableItem(item, cb)
end
+12
View File
@@ -0,0 +1,12 @@
if GetResourceState('LegacyFuel') ~= 'started' then return end
Fuel = {}
Fuel.GetFuel = function(vehicle)
if not DoesEntityExist(vehicle) then return 0.0 end
return exports['LegacyFuel']:GetFuel(vehicle)
end
Fuel.SetFuel = function(vehicle, fuel, type)
if not DoesEntityExist(vehicle) then return end
return exports['LegacyFuel']:SetFuel(vehicle, fuel)
end
+12
View File
@@ -0,0 +1,12 @@
if GetResourceState('Renewed-Fuel') ~= 'started' then return end
Fuel = {}
Fuel.GetFuel = function(vehicle)
if not DoesEntityExist(vehicle) then return 0.0 end
return exports['Renewed-Fuel']:GetFuel(vehicle)
end
Fuel.SetFuel = function(vehicle, fuel, type)
if not DoesEntityExist(vehicle) then return end
return exports['Renewed-Fuel']:SetFuel(vehicle, fuel)
end
+12
View File
@@ -0,0 +1,12 @@
if GetResourceState('cdn-fuel') ~= 'started' then return end
Fuel = {}
Fuel.GetFuel = function(vehicle)
if not DoesEntityExist(vehicle) then return 0.0 end
return exports['cdn-fuel']:GetFuel(vehicle)
end
Fuel.SetFuel = function(vehicle, fuel, type)
if not DoesEntityExist(vehicle) then return end
return exports['cdn-fuel']:SetFuel(vehicle, fuel)
end
+14
View File
@@ -0,0 +1,14 @@
if GetResourceState('cdn-fuel') ~= 'started' then return end
Fuel = {}
Fuel.GetFuel = function(vehicle)
if not DoesEntityExist(vehicle) then return 0.0 end
return Entity(vehicle).state.fuel
end
Fuel.SetFuel = function(vehicle, fuel, type)
if not DoesEntityExist(vehicle) then return end
local currentFuel = Entity(vehicle).state.fuel
Entity(vehicle).state.fuel = currentFuel + fuel
return Entity(vehicle).state.fuel
end
+12
View File
@@ -0,0 +1,12 @@
if GetResourceState('ps-fuel') ~= 'started' then return end
Fuel = {}
Fuel.GetFuel = function(vehicle)
if not DoesEntityExist(vehicle) then return 0.0 end
return exports['ps-fuel']:GetFuel(vehicle)
end
Fuel.SetFuel = function(vehicle, fuel, type)
if not DoesEntityExist(vehicle) then return end
return exports['ps-fuel']:SetFuel(vehicle, fuel)
end
+13
View File
@@ -0,0 +1,13 @@
if GetResourceState('ti_fuel') ~= 'started' then return end
Fuel = {}
Fuel.GetFuel = function(vehicle)
if not DoesEntityExist(vehicle) then return 0.0, type end
local level, type = exports["ti_fuel"]:getFuel(vehicle)
return level, type
end
Fuel.SetFuel = function(vehicle, fuel, type)
if not DoesEntityExist(vehicle) then return end
return exports['ti_fuel']:setFuel(vehicle, fuel, type or "RON91")
end
+13
View File
@@ -0,0 +1,13 @@
if GetResourceState('x-fuel') ~= 'started' then return end
Fuel = {}
Fuel.GetFuel = function(vehicle)
if not DoesEntityExist(vehicle) then return 0.0, type end
local level, type = exports["x-fuel"]:getFuel(vehicle)
return level, type
end
Fuel.SetFuel = function(vehicle, fuel, type)
if not DoesEntityExist(vehicle) then return end
return exports['x-fuel']:SetFuel(vehicle, fuel)
end
+291
View File
@@ -0,0 +1,291 @@
if GetResourceState('ox_lib') ~= 'started' and GetResourceState('qb-menu') ~= 'started' then return end
-- {
-- header = "Test",
-- submitText = "Bill",
-- inputs = {
-- {
-- text = "Citizen ID (#)", -- text you want to be displayed as a place holder
-- name = "citizenid", -- name of the input should be unique otherwise it might override
-- type = "text", -- type of the input
-- isRequired = true, -- Optional [accepted values: true | false] but will submit the form if no value is inputted
-- -- default = "CID-1234", -- Default text option, this is optional
-- },
-- {
-- text = "Secret Code (Give to Nobody)", -- text you want to be displayed as a place holder
-- name = "code", -- name of the input should be unique otherwise it might override
-- type = "password", -- type of the input
-- isRequired = true, -- Optional [accepted values: true | false] but will submit the form if no value is inputted
-- -- default = "password123", -- Default text option, this is optional
-- },
-- {
-- text = "Bill Price ($)", -- text you want to be displayed as a place holder
-- name = "billprice", -- name of the input should be unique otherwise it might override
-- type = "number", -- type of the input - number will not allow non-number characters in the field so only accepts 0-9
-- isRequired = false, -- Optional [accepted values: true | false] but will submit the form if no value is inputted
-- -- default = 1, -- Default number option, this is optional
-- },
-- {
-- text = "Bill Type", -- text you want to be displayed as a input header
-- name = "billtype", -- name of the input should be unique otherwise it might override
-- type = "radio", -- type of the input - Radio is useful for "or" options e.g; billtype = Cash OR Bill OR bank
-- options = { -- The options (in this case for a radio) you want displayed, more than 6 is not recommended
-- { value = "bill", text = "Bill" }, -- Options MUST include a value and a text option
-- { value = "cash", text = "Cash" }, -- Options MUST include a value and a text option
-- { value = "bank", text = "Bank" } -- Options MUST include a value and a text option
-- },
-- -- default = "cash", -- Default radio option, must match a value from above, this is optional
-- },
-- {
-- text = "Include Tax?", -- text you want to be displayed as a input header
-- name = "taxincl", -- name of the input should be unique otherwise it might override
-- type = "checkbox", -- type of the input - Check is useful for "AND" options e.g; taxincle = gst AND business AND othertax
-- options = { -- The options (in this case for a check) you want displayed, more than 6 is not recommended
-- { value = "gst", text = "10% incl."}, -- Options MUST include a value and a text option
-- { value = "business", text = "35% incl.", checked = true }, -- Options MUST include a value and a text option, checked = true is default value, optional
-- { value = "othertax", text = "15% incl."} -- Options MUST include a value and a text option
-- }
-- },
-- {
-- text = "Some Select", -- text you want to be displayed as a input header
-- name = "someselect", -- name of the input should be unique otherwise it might override
-- type = "select", -- type of the input - Select is useful for 3+ amount of "or" options e.g; someselect = none OR other OR other2 OR other3...etc
-- options = { -- Select drop down options, the first option will by default be selected
-- { value = "none", text = "None" }, -- Options MUST include a value and a text option
-- { value = "other", text = "Other"}, -- Options MUST include a value and a text option
-- { value = "other2", text = "Other2" }, -- Options MUST include a value and a text option
-- { value = "other3", text = "Other3" }, -- Options MUST include a value and a text option
-- { value = "other4", text = "Other4" }, -- Options MUST include a value and a text option
-- { value = "other5", text = "Other5" }, -- Options MUST include a value and a text option
-- { value = "other6", text = "Other6" }, -- Options MUST include a value and a text option
-- },
-- -- default = 'other3', -- Default select option, must match a value from above, this is optional
-- }
-- },
-- })
-- local input = lib.inputDialog('Dialog title', {
-- {type = 'input', label = 'Text input', description = 'Some input description', required = true, min = 4, max = 16},
-- {type = 'number', label = 'Number input', description = 'Some number description', icon = 'hashtag'},
-- {type = 'checkbox', label = 'Simple checkbox'},
-- {type = 'color', label = 'Colour input', default = '#eb4034'},
-- {type = 'date', label = 'Date input', icon = {'far', 'calendar'}, default = true, format = "DD/MM/YYYY"}
-- })
--QB types: text, password, number, radio, checkbox, select,
--
-- "input", "number", "checkbox", "select", "multi-select", "slider", "color", "date", "date-range", "time", "textarea",
Input = {}
-- ox to Qb
function OxTypeToQBType(_type)
if _type == "input" then
return "text"
elseif _type == "number" then
return "number"
elseif _type == "checkbox" then
return "checkbox"
elseif _type == "select" then
return "select"
elseif _type == "multi-select" then
return "select"
elseif _type == "slider" then
return "number"
elseif _type == "color" then
return "text"
elseif _type == "date" then
return "date"
elseif _type == "date-range" then
return "date"
elseif _type == "time" then
return "time"
elseif _type == "textarea" then
return "text"
end
end
function OxToQBInput(data)
local returnData = {}
for i, v in pairs(data) do
local input = {
text = v.label,
name = i,
type = OxTypeToQBType(v.type),
isRequired = v.required,
placeholder = v.default,
}
if v.type == "select" then
input.text = ""
input.options = {
{value = v.value, text = v.label}
}
elseif v.type == "checkbox" then
input.text = ""
input.options = {
{value = v.value, text = v.label}
}
end
table.insert(returnData, input)
end
return returnData
end
-- qb to ox
function QBTypeToOxType(_type)
if _type == "text" then
return "input"
elseif _type == "password" then
return "input"
elseif _type == "number" then
return "number"
elseif _type == "radio" then
return "checkbox"
elseif _type == "checkbox" then
return "checkbox"
elseif _type == "select" then
return "select"
end
end
function QBToOxInput(data)
local returnData = {}
for i, v in pairs(data) do
local input = {
label = v.text,
name = i,
type = QBTypeToOxType(v.type),
required = v.isRequired,
default = v.placeholder,
}
if v.type == "select" then
input.options = {}
for i, v in pairs(v.options) do
table.insert(input.options, {value = v.value, label = v.text})
end
elseif v.type == "checkbox" then
for i, v in pairs(v.options) do
table.insert(returnData, {value = v.value, label = v.text})
end
end
table.insert(returnData, input)
end
return returnData
end
--Open menu
function Input.Open(title, data, isQB, submitText)
if isQB then
local inputs = data.inputs
if BridgeClientConfig.InputSystem == "ox" then
return lib.inputDialog(title, QBToOxInput(inputs))
elseif BridgeClientConfig.InputSystem == "qb" then
return exports['qb-input']:ShowInput({
header = title,
submitText = submitText or "Submit",
inputs = inputs
})
end
else
if BridgeClientConfig.InputSystem == "ox" then
return lib.inputDialog(title, data)
elseif BridgeClientConfig.InputSystem == "qb" then
return exports['qb-input']:ShowInput({
header = title,
submitText = submitText or "Submit",
inputs = OxToQBInput(data)
})
end
end
return id
end
--[[
-- Unit tests
local thisIsQB = {
header = "Test",
submitText = "Bill",
inputs = {
{
text = "Citizen ID (#)", -- text you want to be displayed as a place holder
name = "citizenid", -- name of the input should be unique otherwise it might override
type = "text", -- type of the input
isRequired = true, -- Optional [accepted values: true | false] but will submit the form if no value is inputted
-- default = "CID-1234", -- Default text option, this is optional
},
{
text = "Secret Code (Give to Nobody)", -- text you want to be displayed as a place holder
name = "code", -- name of the input should be unique otherwise it might override
type = "password", -- type of the input
isRequired = true, -- Optional [accepted values: true | false] but will submit the form if no value is inputted
-- default = "password123", -- Default text option, this is optional
},
{
text = "Bill Price ($)", -- text you want to be displayed as a place holder
name = "billprice", -- name of the input should be unique otherwise it might override
type = "number", -- type of the input - number will not allow non-number characters in the field so only accepts 0-9
isRequired = false, -- Optional [accepted values: true | false] but will submit the form if no value is inputted
-- default = 1, -- Default number option, this is optional
},
{
text = "Bill Type", -- text you want to be displayed as a input header
name = "billtype", -- name of the input should be unique otherwise it might override
type = "radio", -- type of the input - Radio is useful for "or" options e.g; billtype = Cash OR Bill OR bank
options = { -- The options (in this case for a radio) you want displayed, more than 6 is not recommended
{ value = "bill", text = "Bill" }, -- Options MUST include a value and a text option
{ value = "cash", text = "Cash" }, -- Options MUST include a value and a text option
{ value = "bank", text = "Bank" } -- Options MUST include a value and a text option
},
-- default = "cash", -- Default radio option, must match a value from above, this is optional
},
{
text = "Include Tax?", -- text you want to be displayed as a input header
name = "taxincl", -- name of the input should be unique otherwise it might override
type = "checkbox", -- type of the input - Check is useful for "AND" options e.g; taxincle = gst AND business AND othertax
options = { -- The options (in this case for a check) you want displayed, more than 6 is not recommended
{ value = "gst", text = "10% incl."}, -- Options MUST include a value and a text option
{ value = "business", text = "35% incl.", checked = true }, -- Options MUST include a value and a text option, checked = true is default value, optional
{ value = "othertax", text = "15% incl."} -- Options MUST include a value and a text option
}
},
{
text = "Some Select", -- text you want to be displayed as a input header
name = "someselect", -- name of the input should be unique otherwise it might override
type = "select", -- type of the input - Select is useful for 3+ amount of "or" options e.g; someselect = none OR other OR other2 OR other3...etc
options = { -- Select drop down options, the first option will by default be selected
{ value = "none", text = "None" }, -- Options MUST include a value and a text option
{ value = "other", text = "Other"}, -- Options MUST include a value and a text option
{ value = "other2", text = "Other2" }, -- Options MUST include a value and a text option
{ value = "other3", text = "Other3" }, -- Options MUST include a value and a text option
{ value = "other4", text = "Other4" }, -- Options MUST include a value and a text option
{ value = "other5", text = "Other5" }, -- Options MUST include a value and a text option
{ value = "other6", text = "Other6" }, -- Options MUST include a value and a text option
},
-- default = 'other3', -- Default select option, must match a value from above, this is optional
}
},
}
local thisIsOx = {
{type = 'input', label = 'Text input', description = 'Some input description', required = true, min = 4, max = 16},
{type = 'number', label = 'Number input', description = 'Some number description', icon = 'hashtag'},
{type = 'checkbox', label = 'Simple checkbox'},
{type = 'color', label = 'Colour input', default = '#eb4034'},
{type = 'date', label = 'Date input', icon = {'far', 'calendar'}, default = true, format = "DD/MM/YYYY"}
}
-- qb to ox
RegisterCommand('inputtest1', function()
Input.Open("Test", thisIsQB, true)
end)
-- ox to qb
RegisterCommand('inputtest2', function()
Input.Open("Test", thisIsOx, false)
end)
--]]
@@ -0,0 +1,21 @@
if GetResourceState('codem-inventory') ~= 'started' then return end
Inventory = Inventory or {}
Inventory.GetItemInfo = function(item)
local itemData = exports['codem-inventory']:GetItemList()
if not itemData[item] then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.GetImagePath = function(item)
local imagePath = string.format("nui://codem-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
@@ -0,0 +1,78 @@
if GetResourceState('codem-inventory') ~= 'started' then return end
Inventory = Inventory or {}
Inventory.AddItem = function(src, item, count, slot, metadata)
return exports['codem-inventory']:AddItem(src, item, count, slot, metadata)
end
Inventory.RemoveItem = function(src, item, count, slot, metadata)
if metadata == nil then
return exports['codem-inventory']:RemoveItem(src, item, count, slot)
else
local items = exports['codem-inventory']:GetInventory(nil, src)
for _, itemInfo in pairs(items) do
if itemInfo.name == item then
if itemInfo.info == metadata then
return exports['codem-inventory']:RemoveItem(src, item, count, itemInfo.slot)
end
end
end
end
end
Inventory.GetItemInfo = function(item)
local itemData = exports['codem-inventory']:GetItemList()
if not itemData[item] then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.GetItemCount = function(src, item, metadata)
if metadata == nil then
return exports['codem-inventory']:GetItemsTotalAmount(src, item)
else
local count = 0
local items = exports['codem-inventory']:GetInventory(nil, src)
for _, itemInfo in pairs(items) do
if itemInfo.name == item and itemInfo.info == metadata then
count = count + itemInfo.amount
end
return count
end
end
end
Inventory.GetInventoryItems = function(src)
local items = exports['codem-inventory']:GetInventory(nil, src)
local repackedTable = {}
for _, v in pairs(items) do
table.insert(repackedTable, {
name = v.name,
count = v.amount,
metadata = v.info,
slot = v.slot,
})
end
return items
end
Inventory.SetMetadata = function(src, item, slot, metadata)
exports['codem-inventory']:SetItemMetadata(src, slot, metadata)
end
Inventory.OpenStash = function(src, id, label, slots, weight, owner, groups, coords)
TriggerEvent('codem-inventory:server:openstash', id, slots, weight, label)
end
Inventory.GetImagePath = function(item)
local imagePath = string.format("nui://codem-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
@@ -0,0 +1,23 @@
if GetResourceState('origen_inventory') ~= 'started' then return end
local origen_inventory = exports.origen_inventory
Inventory = Inventory or {}
Inventory.GetItemInfo = function(item)
local itemData = origen_inventory:Items(item)
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable or {}
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("origen_inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://origen_inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
@@ -0,0 +1,79 @@
if GetResourceState('origen_inventory') ~= 'started' then return end
local origen_inventory = exports.origen_inventory
Inventory = Inventory or {}
Inventory.AddItem = function(src, item, count, slot, metadata)
if not origen_inventory:CanCarryItem(src, item, count) then
return Bridge.notify.SendNotify(src, "Inventory Full", "error", 5000)
end
return origen_inventory:AddItem(src, item, count, nil, nil, metadata)
end
Inventory.RemoveItem = function(src, item, count, slot, metadata)
return origen_inventory:RemoveItem(src, item, count, metadata)
end
Inventory.GetItemInfo = function(item)
local itemData = origen_inventory:Items(item)
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable or {}
end
Inventory.GetItemCount = function(src, item, metadata)
if not metadata then
return origen_inventory:GetItemTotalAmount(src, item)
else
local items = origen_inventory:GetInventory(src)
local count = 0
for _, itemInfo in pairs(items) do
if itemInfo.name == item and itemInfo.info == metadata then
count = count + itemInfo.amount
end
end
return count
end
end
Inventory.GetPlayerInventory = function(src)
local playerItems = origen_inventory:GetInventory(src)
local repackedTable = {}
for _, v in pairs(playerItems) do
table.insert(repackedTable, {
name = v.name,
count = v.amount,
metadata = v.info,
slot = v.slot,
})
end
return repackedTable
end
Inventory.CanCarryItem = function(src, item, count)
return origen_inventory:CanCarryItems(src, item, count)
end
Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords)
return origen_inventory:RegisterStash(id, { label = label, slots = slots, weight = weight })
end
Inventory.OpenStash = function(src, id, label, slots, weight, owner, groups, coords)
return origen_inventory:OpenInventory(src, 'stash', id)
end
Inventory.SetMetadata = function(src, item, slot, metadata)
origen_inventory:SetItemMetadata(src, item, slot, metadata)
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("origen_inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://origen_inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+26
View File
@@ -0,0 +1,26 @@
if GetResourceState('ox_inventory') ~= 'started' then return end
local ox_inventory = exports.ox_inventory
Inventory = Inventory or {}
Inventory.GetItemInfo = function(item)
local itemData = ox_inventory:Items(item)
if not itemData then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.stack or "true",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = (itemData.client and itemData.client.image) or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("ox_inventory", string.format("web/images/%s.png", item))
local imagePath = file and string.format("nui://ox_inventory/web/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
--Bridge.RegisterModule("Inventory", Inventory)
+67
View File
@@ -0,0 +1,67 @@
if GetResourceState('ox_inventory') ~= 'started' then return end
local ox_inventory = exports.ox_inventory
Inventory = Inventory or {}
Inventory.AddItem = function(src, item, count, slot, metadata)
return ox_inventory:AddItem(src, item, count, metadata)
end
Inventory.RemoveItem = function(src, item, count, slot, metadata)
return ox_inventory:RemoveItem(src, item, count, metadata, slot)
end
Inventory.GetItem = function(src, item, metadata)
return ox_inventory:GetItem(src, item, metadata, false)
end
Inventory.GetItemCount = function(src, item, metadata)
return ox_inventory:GetItemCount(src, item, metadata, false)
end
Inventory.GetPlayerInventory = function(src)
return ox_inventory:GetInventoryItems(src, false)
end
Inventory.CanCarryItem = function(src, item, count)
return ox_inventory:CanCarryItem(src, item, count)
end
Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords)
return ox_inventory:RegisterStash(id, label, slots, weight, owner)
end
Inventory.OpenStash = function(src, id, label, slots, weight, owner, groups, coords)
TriggerClientEvent('ox_inventory:openInventory', src, 'stash', 'stash_' .. id)
end
Inventory.GetItemInfo = function(item)
local itemData = ox_inventory:Items(item)
if not itemData then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.stack or "true",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.client.image or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.SetMetadata = function(src, item, slot, metadata)
ox_inventory:SetMetadata(src, slot, metadata)
end
Inventory.UpdatePlate = function(oldplate, newplate)
ox_inventory:UpdateVehicle(oldplate, newplate)
if GetResourceState('jg-mechanic') ~= 'started' then return end
exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate)
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("ox_inventory", string.format("web/images/%s.png", item))
local imagePath = file and string.format("nui://ox_inventory/web/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+15
View File
@@ -0,0 +1,15 @@
if GetResourceState('ps-inventory') ~= 'started' then return end
Inventory = Inventory or {}
RegisterNetEvent('community_bridge:client:ps-inventory:openStash', function(id, data)
if source ~= 65535 then return end
TriggerEvent('ps-inventory:client:SetCurrentStash', id)
TriggerServerEvent('ps-inventory:server:OpenInventory', 'stash', id, { maxweight = data.weight, slots = data.slots })
end)
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("ps-inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://ps-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+17
View File
@@ -0,0 +1,17 @@
if GetResourceState('ps-inventory') ~= 'started' then return end
Inventory = Inventory or {}
Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords)
return true
end
Inventory.OpenStash = function(src, id, label, slots, weight, owner, groups, coords)
TriggerClientEvent('community_bridge:client:ps-inventory:openStash', src, id, { label = label, maxweight = weight, slots = slots, })
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("ps-inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://ps-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+15
View File
@@ -0,0 +1,15 @@
if GetResourceState('qb-inventory') ~= 'started' then return end
Inventory = Inventory or {}
RegisterNetEvent('community_bridge:client:qb-inventory:openStash', function(id, data)
if source ~= 65535 then return end
TriggerEvent("inventory:client:SetCurrentStash", id)
TriggerServerEvent('inventory:server:OpenInventory', 'stash', id, { maxweight = data.weight, slots = data.slots })
end)
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("qb-inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://qb-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+17
View File
@@ -0,0 +1,17 @@
if GetResourceState('qb-inventory') ~= 'started' then return end
Inventory = Inventory or {}
Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords)
return true
end
Inventory.OpenStash = function(src, id, label, slots, weight, owner, groups, coords)
TriggerClientEvent('community_bridge:client:qb-inventory:openStash', src, id, { weight = weight, slots = slots })
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("qb-inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://qb-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+27
View File
@@ -0,0 +1,27 @@
if GetResourceState('qs-inventory') ~= 'started' then return end
Inventory = Inventory or {}
Inventory.OpenStash = function(id)
exports['qs-inventory']:RegisterStash(id, 50, 50000)
end
Inventory.GetItemInfo = function(item)
local itemData = exports['qs-inventory']:GetItemList()
if not itemData[item] then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("qs-inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://qs-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+67
View File
@@ -0,0 +1,67 @@
if GetResourceState('qs-inventory') ~= 'started' then return end
Inventory = Inventory or {}
Inventory.AddItem = function(src, item, count, slot, metadata)
if not exports['qs-inventory']:CanCarryItem(src, item, count) then return false end
return exports['qs-inventory']:AddItem(src, item, count, slot, metadata)
end
Inventory.RemoveItem = function(src, item, count, slot, metadata)
return exports['qs-inventory']:RemoveItem(src, item, count, slot, metadata)
end
Inventory.GetItemCount = function(src, item, metadata)
return exports['qs-inventory']:GetItemTotalAmount(src, item)
end
Inventory.GetPlayerInventory = function(src)
local playerItems = exports['qs-inventory']:GetInventory(src)
local repackedTable = {}
for _, v in pairs(playerItems) do
table.insert(repackedTable, {
name = v.name,
count = v.amount,
metadata = v.info,
slot = v.slot,
})
end
return repackedTable
end
Inventory.CanCarryItem = function(src, item, count)
return exports['qs-inventory']:CanCarryItem(src, item, count)
end
Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords)
return true
end
Inventory.OpenStash = function(src, id, label, slots, weight, owner, groups, coords)
TriggerEvent("inventory:server:OpenInventory", "stash", id, { maxweight = weight, slots = slots })
TriggerClientEvent("inventory:client:SetCurrentStash",src, id)
end
Inventory.GetItemInfo = function(item)
local itemData = exports['qs-inventory']:GetItemList()
if not itemData[item] then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.SetMetadata = function(src, item, slot, metadata)
return exports['qs-inventory']:SetItemMetadata(src, slot, metadata)
end
Inventory.GetImagePath = function(item)
local file = LoadResourceFile("qs-inventory", string.format("html/images/%s.png", item))
local imagePath = file and string.format("nui://qs-inventory/html/images/%s.png", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
@@ -0,0 +1,29 @@
if GetResourceState('tgiann-inventory') ~= 'started' then return end
local tgiann = exports["tgiann-inventory"]
Inventory = Inventory or {}
Inventory.OpenStash = function(id)
-- open stash export... not sure what it is yet.
end
Inventory.GetItemInfo = function(item)
local itemData = tgiann:GetItemList()
if not itemData[item] then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.GetImagePath = function(item)
local pngPath = LoadResourceFile("inventory_images", string.format("html/images/%s.png", item))
local webpPath = LoadResourceFile("inventory_images", string.format("html/images/%s.webp", item))
local imagePath = pngPath and string.format("nui://inventory_images/html/images/%s.png", item) or webpPath and string.format("nui://inventory_images/html/images/%s.webp", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
@@ -0,0 +1,63 @@
if GetResourceState('tgiann-inventory') ~= 'started' then return end
local tgiann = exports["tgiann-inventory"]
Inventory = Inventory or {}
Inventory.AddItem = function(src, item, count, slot, metadata)
if not tgiann:CanCarryItem(src, item, count) then return false end
local action = tgiann:AddItem(src, item, count, metadata)
return (action.itemAddRemoveLog == 'added')
end
Inventory.RemoveItem = function(src, item, count, slot, metadata)
return tgiann:RemoveItem(src, item, count, nil, metadata)
end
Inventory.GetItem = function(src, item, metadata)
local item = tgiann:GetItemByName(src, item, metadata)
item.count = item.amount
item.metadata = item.info
return item
end
Inventory.GetItemCount = function(src, item, metadata)
local _item = tgiann:GetItemByName(src, item, metadata)
return _item.amount or 0
end
Inventory.GetInventoryItems = function(src)
return tgiann:GetPlayerItems(src)
end
Inventory.CanCarryItem = function(src, item, count)
return tgiann:CanCarryItem(src, item, count)
end
Inventory.RegisterStash = function(id, label, slots, weight, owner)
return tgiann:CreateCustomStashWithItem(id, {})
end
Inventory.GetItemInfo = function(item)
local itemData = tgiann:GetItemList()
if not itemData[item] then return {} end
local repackedTable = {
name = itemData.name or "Missing Name",
label = itemData.label or "Missing Label",
stack = itemData.unique or "false",
weight = itemData.weight or "0",
description = itemData.description or "none",
image = itemData.image or Inventory.GetImagePath(item),
}
return repackedTable
end
Inventory.SetMetadata = function(src, item, slot, metadata)
tgiann:UpdateItemMetadata(src, item, slot, metadata)
end
Inventory.GetImagePath = function(item)
local pngPath = LoadResourceFile("inventory_images", string.format("html/images/%s.png", item))
local webpPath = LoadResourceFile("inventory_images", string.format("html/images/%s.webp", item))
local imagePath = pngPath and string.format("nui://inventory_images/html/images/%s.png", item) or webpPath and string.format("nui://inventory_images/html/images/%s.webp", item)
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
end
+15
View File
@@ -0,0 +1,15 @@
if GetResourceState('MrNewbVehicleKeys') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
if not DoesEntityExist(vehicle) then return false end
return exports.MrNewbVehicleKeys:GiveKeys(vehicle)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
if not vehicle and not plate then return false end
if not DoesEntityExist(vehicle) then
return exports.MrNewbVehicleKeys:RemoveKeysByPlate(plate)
end
return exports.MrNewbVehicleKeys:RemoveKeys(vehicle)
end
@@ -0,0 +1,12 @@
if GetResourceState('Renewed-Vehiclekeys') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
if not DoesEntityExist(vehicle) then return false end
return exports['Renewed-Vehiclekeys']:addKey(plate)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
if not DoesEntityExist(vehicle) then return false end
return exports['Renewed-Vehiclekeys']:removeKey(plate)
end
+10
View File
@@ -0,0 +1,10 @@
if GetResourceState('cd_garage') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
TriggerEvent('cd_garage:AddKeys', plate)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
end
+12
View File
@@ -0,0 +1,12 @@
if GetResourceState('mk_vehiclekeys') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
if not DoesEntityExist(vehicle) then return false end
return exports["mk_vehiclekeys"]:AddKey(vehicle)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
if not DoesEntityExist(vehicle) then return false end
return exports["mk_vehiclekeys"]:RemoveKey(vehicle)
end
+10
View File
@@ -0,0 +1,10 @@
if GetResourceState('okokGarage') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
TriggerServerEvent('okokGarage:GiveKeys', plate)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
end
+11
View File
@@ -0,0 +1,11 @@
if GetResourceState('qb-vehiclekeys') ~= 'started' then return end
if GetResourceState('qbx_vehiclekeys') == 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', plate)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
end
+10
View File
@@ -0,0 +1,10 @@
if GetResourceState('qbx_vehiclekeys') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', plate)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
end
+12
View File
@@ -0,0 +1,12 @@
if GetResourceState('qs-vehiclekeys') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
local model = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))
local verifiedPlate = GetVehicleNumberPlateText(vehicle)
exports['qs-vehiclekeys']:GiveKeys(verifiedPlate, model, true)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
end
+12
View File
@@ -0,0 +1,12 @@
if GetResourceState('t1ger_keys') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
if not DoesEntityExist(vehicle) then return false end
local vehicle_display_name = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))
return exports['t1ger_keys']:GiveTemporaryKeys(plate, vehicle_display_name, 'some_keys')
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
end
+10
View File
@@ -0,0 +1,10 @@
if GetResourceState('wasabi_carlock') ~= 'started' then return end
VehicleKeys = {}
VehicleKeys.GiveKeys = function(vehicle, plate)
exports.wasabi_carlock:GiveKey(plate)
end
VehicleKeys.RemoveKeys = function(vehicle, plate)
exports.wasabi_carlock:RemoveKey(plate)
end
+59
View File
@@ -0,0 +1,59 @@
local ConvarLang = GetConvar("lang", "none")
local OXLang = GetConvar("ox:locale", "none")
local QBXLang = GetConvar("qb_locale", "none")
local txLang = GetConvar("txAdmin-locale", "none")
local esxLang = GetConvar("esx:locale", "none")
BridgeSharedConfig = Require("settings/sharedConfig.lua")
Lang = ConvarLang ~= "none" and
ConvarLang or BridgeSharedConfig.Lang ~= "auto" and BridgeSharedConfig.Lang or
OXLang ~= "none" and OXLang or
QBXLang ~= "none" and QBXLang or
txLang ~= "none" and txLang or
esxLang ~= "none" and esxLang or
"en"
Language = {}
function Language.Locale(str, ...)
local resource = GetInvokingResource() or GetCurrentResourceName()
assert(resource, "Resource name not found")
print(resource, "locales/" .. Lang .. ".json")
local locales = LoadResourceFile(resource, "locales/" .. Lang .. ".json")
print(locales, Lang)
locales = locales and json.decode(locales) or {}
local locale = locales[str]
if not locale then
warn("Locale not found for language: " .. Lang)
return str
end
local args = {...}
if #args > 0 then
for i = 1, #args do
locale = locale:gsub('{' .. i .. '}', args[i])
end
end
return locale
end
if BridgeSharedConfig.DebugLevel == 3 then
-- if outside this resource, use local whatever = Require("modules/locales/shared.lua")
-- whatever.Locales("some-index-in-language-.json-file")
-- Files must be stored in "locales" folder, within the resource.
-- Instead of using Require you can also import it via the manifest.
-- The Lang variable is available globally, which tells you what the server is using.
print("Language: ", Lang)
print("Locale: ", Language.Locale("locale-unit-test"))
-- Example outside community bridge resource:
-- local Language = Require('modules/locales/shared.lua')
-- print("Language: ", Lang)
-- print("Locale: ", Language.Locale("locale-unit-test"))
end
return Language
@@ -0,0 +1,14 @@
if GetResourceState('Renewed-Banking') ~= 'started' then return end
Managment = {}
Managment.GetAccountMoney = function(account)
return exports['Renewed-Banking']:getAccountMoney(account)
end
Managment.AddAccountMoney = function(account, amount)
return exports['Renewed-Banking']:addAccountMoney(account, amount)
end
Managment.RemoveAccountMoney = function(account, amount)
return exports['Renewed-Banking']:removeAccountMoney(account, amount)
end
+14
View File
@@ -0,0 +1,14 @@
if GetResourceState('okokBanking') ~= 'started' then return end
Managment = {}
Managment.GetAccountMoney = function(account)
return exports['okokBanking']:GetAccount(account)
end
Managment.AddAccountMoney = function(account, amount)
return exports['okokBanking']:AddMoney(account, amount)
end
Managment.RemoveAccountMoney = function(account, amount)
return exports['okokBanking']:RemoveMoney(account, amount)
end
+14
View File
@@ -0,0 +1,14 @@
if GetResourceState('qb-banking') ~= 'started' then return end
Managment = {}
Managment.GetAccountMoney = function(account)
return exports['qb-banking']:GetAccountBalance(account)
end
Managment.AddAccountMoney = function(account, amount)
return exports['qb-banking']:AddMoney(account, amount)
end
Managment.RemoveAccountMoney = function(account, amount)
return exports['qb-banking']:RemoveMoney(account, amount)
end
+68
View File
@@ -0,0 +1,68 @@
---@class Math
------@field public name string @add name field to class Car, you'll see it in code completion
Math = {}
--- If the value is less than the minimum, it will return the minimum.
--- If the value is greater than the maximum, it will return the maximum.
--- Otherwise, it will return the value.
---@param value number: The value to clamp.
---@param min number: The minimum value.
---@param max number: The maximum value.
---@return number: The clamped value.
function Math.Clamp(value, min, max)
if value < min then
return min
elseif value > max then
return max
else
return value
end
end
--- Rounds a number to the nearest whole number.
---@param value number: The value to round.
---@return number: The rounded value.
function Math.Round(value)
return math.floor(value + 0.5)
end
function Math.Truncate(value, decimals)
local mul = decimals and (10 ^ decimals) or 1
if value < 0 then
return math.ceil(value * mul) / mul
else
return math.floor(value * mul) / mul
end
end
--- Warps the number around from max to min and vice versa.
---@param value number: The value to wrap.
---@param min number: The minimum value.
---@param max number: The maximum value.
---@return number: The wrapped value.
function Math.Wrap(value, min, max)
local range = max - min
return (value - min) % range + min
end
--- Gets an interpolated value between two numbers.
---@see https://en.wikipedia.org/wiki/Smoothstep
---@param value number The interpolation value.
---@param min number : The minimum value.
---@param max number : The maximum value.
---@return number The interpolated value.
function Math.Smooth(value, min, max)
value = Math.Clamp((value - min) / (max - min), 0, 1)
return value * value * (3 - 2 * value)
end
--- Maps a value from one range to another.
---@param value number The value to map.
---@param inMin number The minimum value for the provided value.
---@param inMax number The maximum value for the provided value.
---@param outMin number The minimum value for the output.
---@param outMax number The maximum value for the output.
function Math.Map(value, inMin, inMax, outMin, outMax)
return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin
end
+207
View File
@@ -0,0 +1,207 @@
local Menus = {}
Menu = {}
if GetResourceState('ox_lib') ~= 'started' and GetResourceState('qb-menu') ~= 'started' then return end
--- Converts a QB menu to an Ox menu.
---@param id string The menu ID.
---@param menu table The QB menu data.
---@return table The Ox menu data.
function QBToOxMenu(id, menu)
local oxMenu = {
id = id,
title = "",
canClose = true,
options = {},
}
for i, v in pairs(menu) do
if v.isMenuHeader then
if oxMenu.title == "" then
oxMenu.title = v.header
end
else
local option = {
title = v.header,
description = v.txt,
icon = v.icon,
args = v.params.args,
onSelect = function(selected, secondary, args)
local params = menu[id]?.options?[selected]?.params
if not params then return end
local event = params.event
local isServer = params.isServer
if not event then return end
if isServer then
return TriggerServerEvent(event, args)
end
return TriggerEvent(event, args)
end
}
table.insert(oxMenu.options, option)
end
end
return oxMenu
end
--- Converts an Ox menu to a QB menu.
---@param id string The menu ID.
---@param menu table The Ox menu data.
---@return table The QB menu data.
function OxToQBMenu(id, menu)
local qbMenu = {
{
header = menu.title,
isMenuHeader = true,
}
}
for i, v in pairs(menu.options) do
local button = {
header = v.title,
txt = v.description,
icon = v.icon,
}
if v.onSelect and type(v.onSelect) == 'function' then
button.params = {
event = "community_bridge:client:MenuCallback",
args = {id = id, selected = i, args = v.args, onSelect = v.onSelect},
}
end
table.insert(qbMenu, button)
end
return qbMenu
end
--- Opens a menu based on the configuration.
---@param data table The menu data.
---@param useQb boolean Whether to use QB menu syntax.
---@return id string The menu ID.
function Menu.Open(data, useQb)
--local id = data.id or CreateUniqueId(Menus)
local id = data.id or Ids.CreateUniqueId(Menus, nil, nil)
local menuExists = Menus[id]
if useQb then
if BridgeClientConfig.MenuSystem == "ox" then
if not menuExists then
Menus[id] = QBToOxMenu(id, data)
lib.registerContext(Menus[id])
end
return lib.showContext(id)
elseif BridgeClientConfig.MenuSystem == "qb" then
Menus[id] = data
return exports['qb-menu']:openMenu(Menus[id])
end
else
if BridgeClientConfig.MenuSystem == "ox" then
if not menuExists then
Menus[id] = data
lib.registerContext(Menus[id])
end
return lib.showContext(id)
elseif BridgeClientConfig.MenuSystem == "qb" then
Menus[id] = OxToQBMenu(id, data)
return exports['qb-menu']:openMenu(Menus[id])
end
end
return id
end
--- Event to handle callback from menu selection.
--- @param _args table The arguments passed to the callback.
--- @return nil
RegisterNetEvent('community_bridge:client:MenuCallback', function(_args)
local id = _args.id
local onSelect = _args.onSelect
local args = _args.args
if not Menus[id] then return end
onSelect({number=_args.selected}, false, args)
end)
--[[
--Unit Tests
local qbMenu = {
{
header = 'QBCore Test Menu',
icon = 'fas fa-code',
isMenuHeader = true, -- Set to true to make a nonclickable title
},
{
header = 'First Button',
txt = 'Open a secondary menu!',
icon = 'fas fa-code-pull-request',
-- disabled = false, -- optional, non-clickable and grey scale
-- hidden = true, -- optional, hides the button completely
params = {
-- isServer = false, -- optional, specify event type
event = 'community_bridge:client:TestEvent',
args = {
number = 1,
}
}
},
{
header = 'Second Button',
txt = 'Open a secondary menu!',
icon = 'fas fa-code-pull-request',
params = {
event = 'community_bridge:client:TestEvent',
args = {
number = 2,
}
}
}
}
local oxMenu = {
id = "test",
title = "Test Menu",
options = {
{
title = "First Button",
description = "Open a secondary menu!",
icon = "fas fa-code-pull-request",
args = {
number = 1,
},
onSelect = function(selected, secondary, args)
print("Selected", json.encode(selected))
end
},
{
title = "Second Button",
description = "Open a secondary menu!",
icon = "fas fa-code-pull-request",
args = {
number = 2,
},
onSelect = function(selected, secondary, args)
print("Selected", json.encode(selected))
end
}
}
}
RegisterCommand("testmenu-qbtoox", function()
Menu.Open(qbMenu, true)
end)
RegisterCommand("testmenu-oxtoqb", function()
Menu.Open(oxMenu, false)
end)
RegisterCommand("testmenu-oxtoox", function()
Menu.Open(oxMenu, false)
end)
RegisterCommand("testmenu-qbtoqb", function()
Menu.Open(qbMenu, true)
end)
RegisterNetEvent('community_bridge:client:TestEvent', function(args)
print("Test Event", json.encode(args))
end)
--]]
+66
View File
@@ -0,0 +1,66 @@
function InternalNotify(message, type, time)
if BridgeClientConfig == nil or BridgeClientConfig.NotifySystem == nil then return Prints.error("You have not configured a compatable notify in community_bridge") end
local notifyType = BridgeClientConfig.NotifySystem
time = time or 3000
if notifyType == 'qb' then
return TriggerEvent('QBCore:Notify', message, 'primary', time)
elseif notifyType == 'mythic_notify' then
return exports['mythic_notify']:SendAlert('inform', message, time)
elseif notifyType == 'pNotify' then
return exports['pNotify']:SendNotification({ text = message, type = type, timeout = time, layout = 'centerRight' })
elseif notifyType == 'esx_notify' then
return ESX.ShowNotification(message, type, time)
elseif notifyType == 'ox' then
return exports.ox_lib:notify({ description = message, type = type, position = 'top' })
elseif notifyType == 't-notify' then
return exports['t-notify']:Alert({ style = 'info', message = message, duration = time, })
elseif notifyType == 'wasabi_notify' then
return exports.wasabi_notify:notify(type, message, time, type)
elseif notifyType == 'lab' then
return exports['swe-notify']:SendNotification(message, time, type)
elseif notifyType == 'custom' then
return Prints.error("You have not set up a custom notify in community_bridge")
else
return Prints.error("You have not configured a notify in community_bridge")
end
end
function InternalShowHelpText(message, position)
if BridgeClientConfig == nil or BridgeClientConfig.ShowHelpText == nil then return Prints.error("You have not configured a compatable helptext in community_bridge") end
local helptextType = BridgeClientConfig.ShowHelpText
if helptextType == 'ox' then
return exports.ox_lib:showTextUI(message, { position = 'left-center' })
elseif helptextType == 'jg' then
return exports['jg-textui']:DrawText(message)
elseif helptextType == 'qb' then
return exports['qb-core']:DrawText(message, 'left')
elseif helptextType == 'lab' then
return exports['lab-HintUI']:Show(message, "Hint Text")
elseif helptextType == 'custom' then
return Prints.error("You have not set up a custom ShowHelpText in community_bridge")
else
return Prints.error("You have not configured a ShowHelpText in community_bridge")
end
end
function InternalHideHelpText()
if BridgeClientConfig == nil or BridgeClientConfig.ShowHelpText == nil then return Prints.error("You have not configured a compatable helptext in community_bridge") end
local helptextType = BridgeClientConfig.ShowHelpText
if helptextType == 'ox' then
return exports.ox_lib:hideTextUI()
elseif helptextType == 'jg' then
return exports['jg-textui']:HideText()
elseif helptextType == 'qb' then
return exports['qb-core']:HideText()
elseif helptextType == 'lab' then
return exports['lab-HintUI']:Hide()
elseif helptextType == 'custom' then
return Prints.error("You have not set up a custom HideHelpText in community_bridge")
else
return Prints.error("You have not configured a HideHelpText in community_bridge")
end
end
RegisterNetEvent('community_bridge:Client:Notify', function(message, type, time)
InternalNotify(message, type, time)
end)
+5
View File
@@ -0,0 +1,5 @@
Notify = {}
Notify.SendNotify = function(src, message, type, time)
TriggerClientEvent('community_bridge:Client:Notify', src, message, type, time)
end
+6
View File
@@ -0,0 +1,6 @@
if GetResourceState('gksphone') ~= 'started' then return end
Phones = {}
Phones.SendEmail = function(email, title, message)
return exports["gksphone"]:SendNewMail({ sender = email, image = '/html/static/img/icons/mail.png', subject = title, message = message })
end
+16
View File
@@ -0,0 +1,16 @@
if GetResourceState('gksphone') ~= 'started' then return end
Phones = {}
Phones.GetPlayerPhone = function(src)
return exports["gksphone"]:GetPhoneBySource(src) or false
end
Phones.SendEmail = function(src, email, title, message)
local data = {}
data.sender = email
data.image = '/html/static/img/icons/mail.png'
data.subject = title
data.message = message
exports["gksphone"]:SendNewMail(src, data)
return true
end
+6
View File
@@ -0,0 +1,6 @@
if GetResourceState('lb-phone') ~= 'started' then return end
Phones = {}
Phones.SendEmail = function(email, title, message)
TriggerServerEvent('community_bridge:Server:genericEmail', {email = email, title = title, message = message})
end
+26
View File
@@ -0,0 +1,26 @@
if GetResourceState('lb-phone') ~= 'started' then return end
Phones = {}
Phones.GetPlayerPhone = function(src)
return exports["lb-phone"]:GetEquippedPhoneNumber(src) or false
end
Phones.SendEmail = function(src, email, title, message)
local numberNumber = exports["lb-phone"]:GetEquippedPhoneNumber(src)
if not numberNumber then return false, print("Could not Find Phone number") end
local playerEmail = exports["lb-phone"]:GetEmailAddress(numberNumber)
if not playerEmail then return false, print("Could not Find email") end
local success, id = exports["lb-phone"]:SendMail({
to = playerEmail,
sender = email,
subject = title,
message = message,
})
return success
end
RegisterNetEvent('community_bridge:Server:genericEmail', function(data)
local src = source
print('community_bridge:Server:genericEmail Hit')
return Phones.SendEmail(src, data.email, data.title, data.message)
end)
+11
View File
@@ -0,0 +1,11 @@
if GetResourceState('qs-smartphone') ~= 'started' then return end
Phones = {}
Phones.SendEmail = function(email, title, message)
return TriggerServerEvent('qs-smartphone:server:sendNewMail', { sender = email, subject = title, message = message, button = {} })
end
RegisterNetEvent('community_bridge:Server:genericEmail', function(data)
TriggerServerEvent('qs-smartphone:server:sendNewMail', { sender = data.email, subject = data.title, message = data.message, button = {} })
return true
end)
+11
View File
@@ -0,0 +1,11 @@
if GetResourceState('qs-smartphone') ~= 'started' then return end
Phones = {}
Phones.GetPlayerPhone = function(src)
return exports['qs-base']:GetPlayerPhone(src) or false
end
Phones.SendEmail = function(src, email, title, message)
TriggerClientEvent('community_bridge:Server:genericEmail', src, { sender = email, subject = title, message = message, button = {} })
return true
end
+37
View File
@@ -0,0 +1,37 @@
Points = {}
local ActivePoints = {}
Points.RegisterPoint = function(pointCoords, pointDistance, pointOnEnter, pointOnExit)
local enterZone = lib.points.new({
coords = pointCoords,
distance = pointDistance,
onEnter = function(self)
pointOnEnter(self)
end,
onExit = function(self)
pointOnExit(self)
end,
})
local pointID = Ids.CreateUniqueId(nil, 5, nil)
ActivePoints[pointID] = enterZone
return enterZone, pointID
end
-- Function to retrieve the enterZone using pointID
Points.GetPointById = function(pointID)
return ActivePoints[pointID]
end
Points.RemovePoint = function(pointID)
local point = ActivePoints[pointID]
if point then
print("Removing point with ID " .. pointID)
point:remove() -- Call the remove method on the point (ensure this method stops all event listeners)
ActivePoints[pointID] = nil -- Remove from ActivePoints table
print("Point removed successfully.")
return true
else
print("Point with ID " .. pointID .. " not found.")
return false
end
end
@@ -0,0 +1,38 @@
if BridgeClientConfig.ProgressBar ~= "ox" then return end
ProgressBar = {}
local _progBarType = BridgeClientConfig.ProgressBarStyle or "bar"
ProgressBar.StartProgressBar = function(time, label, whiledead, cancancel, disable, animTable, successAction, canceledAction)
local runTime = time or 10000
local textLabel = label or "Doing something"
local deadBool = whiledead or false
local cancelBool = cancancel or false
local disableKeys = disable or { move = true, sprint = true, car = true, combat = true, }
local anim = animTable or nil
local success = successAction or function() print("Success") end
local canceled = canceledAction or function() print("Cancelled") end
if _progBarType == "bar" then
if exports.ox_lib:progressBar({
duration = runTime,
label = textLabel,
useWhileDead = deadBool,
canCancel = cancelBool,
disable = disableKeys,
anim = anim,
}) then success() else canceled() end
elseif _progBarType == "circle" then
if exports.ox_lib:progressCircle({
duration = runTime,
label = textLabel,
position = 'bottom',
useWhileDead = deadBool,
canCancel = cancelBool,
disable = disableKeys,
anim = anim,
}) then success() else canceled() end
end
end
ProgressBar.IsProgressBarActive = function()
return exports.ox_lib:progressActive()
end
@@ -0,0 +1,60 @@
if BridgeClientConfig.ProgressBar ~= "qb" then return end
ProgressBar = {}
local function convertOxToQB(disabledTable, animTable)
local repackedTable = { disabled = {}, animations = {}}
for _, v in pairs(disabledTable) do
if v.move then
repackedTable.disabled.disableMovement = v.move
end
if v.car then
repackedTable.disabled.disableCarMovement = v.car
end
if v.combat then
repackedTable.disabled.disableCombat = v.combat
end
if v.mouse then
repackedTable.disabled.disableMouse = v.mouse
end
end
for _, v in pairs(animTable) do
if v.dict then
repackedTable.animations.animDict = v.animDict
end
if v.clip then
repackedTable.animations.anim = v.anim
end
end
return repackedTable
end
ProgressBar.StartProgressBar = function(time, label, whiledead, cancancel, disable, animTable, successAction, canceledAction)
local runTime = time or 10000
local textLabel = label or "Doing something"
local deadBool = whiledead or false
local cancelBool = cancancel or false
local success = successAction or function() print("Success") end
local canceled = canceledAction or function() print("Cancelled") end
local repackedTable = convertOxToQB(disable, animTable)
exports['progressbar']:Progress({
name = "random_task",
duration = runTime,
label = textLabel,
useWhileDead = deadBool,
canCancel = cancelBool,
controlDisables = repackedTable.disabled,
animation = repackedTable.animations,
prop = {},
propTwo = {}
}, function(cancelled)
if not cancelled then
success()
else
canceled()
end
end)
end
ProgressBar.IsProgressBarActive = function()
return exports["progressbar"]:isDoingSomething()
end
+3
View File
@@ -0,0 +1,3 @@
Stashes = {}
-- Needs Redone
+72
View File
@@ -0,0 +1,72 @@
if GetResourceState('ox_target') ~= 'started' then return end
local targetDebug = false
local function detectDebugEnabled()
if BridgeClientConfig.DebugLevel == 3 then
targetDebug = true
end
end
detectDebugEnabled()
local ox_target = exports.ox_target
local targetZones = {}
Target = {}
Target.AddGlobalPlayer = function(options)
ox_target:addGlobalPlayer(options)
end
Target.AddLocalEntity = function(entities, options)
ox_target:addLocalEntity(entities, options)
end
Target.AddModel = function(models, options)
ox_target:addModel(models, options)
end
Target.AddBoxZone = function(name, coords, size, heading, options)
local target = ox_target:addBoxZone({
coords = coords,
size = size,
rotation = heading,
debug = targetDebug,
options = options,
})
table.insert(targetZones, { name = name, id = target, creator = GetInvokingResource() })
return target
end
Target.RemoveGlobalPlayer = function()
ox_target:removeGlobalPlayer()
end
Target.RemoveLocalEntity = function(entity)
ox_target:removeLocalEntity(entity)
end
Target.RemoveModel = function(model)
ox_target:removeModel(model)
end
Target.RemoveZone = function(name)
for _, data in pairs(targetZones) do
if data.name == name then
ox_target:removeZone(data.id)
table.remove(targetZones, _)
break
end
end
end
AddEventHandler('onResourceStop', function(resource)
if resource ~= GetCurrentResourceName() then
for _, target in pairs(targetZones) do
if target.creator == resource then
ox_target:removeZone(target.id)
end
end
targetZones = {}
end
end)
+94
View File
@@ -0,0 +1,94 @@
if GetResourceState('qb-target') ~= 'started' or GetResourceState('ox_target') == 'started' then return end
local targetDebug = false
local function detectDebugEnabled()
if BridgeClientConfig.DebugLevel == 3 then
targetDebug = true
end
end
detectDebugEnabled()
local targetZones = {}
Target = {}
Target.AddGlobalPlayer = function(options)
for k, v in pairs(options) do
options[k].action = v.onSelect
end
exports['qb-target']:AddGlobalPlayer({
options = options,
distance = options.distance or 1.5
})
end
Target.AddLocalEntity = function(entities, options)
for k, v in pairs(options) do
options[k].action = v.onSelect
end
exports['qb-target']:AddTargetEntity(entities, {
options = options,
distance = options.distance or 1.5
})
end
Target.AddModel = function(models, options)
for k, v in pairs(options) do
options[k].action = v.onSelect
end
exports['qb-target']:AddTargetModel(models, {
options = options,
distance = options.distance or 1.5,
})
end
Target.AddBoxZone = function(name, coords, size, heading, options)
for k, v in pairs(options) do
options[k].action = v.onSelect
end
exports['qb-target']:AddBoxZone(name, coords, size.x, size.y, {
name = name,
debugPoly = targetDebug,
heading = heading,
minZ = coords.z - (size.x * 0.5),
maxZ = coords.z + (size.x * 0.5),
}, {
options = options,
distance = options.distance or 1.5,
})
table.insert(targetZones, { name = name, creator = GetInvokingResource() })
end
Target.RemoveGlobalPlayer = function()
exports['qb-target']:RemoveGlobalPlayer()
end
Target.RemoveLocalEntity = function(entity)
exports['qb-target']:RemoveTargetEntity(entity)
end
Target.RemoveModel = function(model)
exports['qb-target']:RemoveTargetModel(model)
end
Target.RemoveZone = function(name)
for _, data in pairs(targetZones) do
if data.name == name then
exports['qb-target']:RemoveZone(name)
table.remove(targetZones, _)
break
end
end
end
AddEventHandler('onResourceStop', function(resource)
if resource ~= GetCurrentResourceName() then
for _, target in pairs(targetZones) do
if target.creator == resource then
exports['qb-target']:RemoveZone(target.name)
end
end
targetZones = {}
end
end)
+251
View File
@@ -0,0 +1,251 @@
Utility = {}
local blipIDs = {}
local spawnedPeds = {}
lib.locale()
Utility.CreateVehicle = function(model, coords, heading, networked)
if networked == nil then networked = true end
Utility.LoadModel(model)
if not HasModelLoaded(model) then return Prints.error("Model Has Not Loaded") end
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, networked, false)
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
SetVehicleNeedsToBeHotwired(vehicle, false)
SetModelAsNoLongerNeeded(model)
SetVehRadioStation(vehicle, "OFF")
return vehicle, { networkid = NetworkGetNetworkIdFromEntity(vehicle) or 0, coords = GetEntityCoords(vehicle), heading = GetEntityHeading(vehicle), }
end
Utility.StartBusySpinner = function(text)
AddTextEntry(text, text)
BeginTextCommandBusyString(text)
AddTextComponentSubstringPlayerName(text)
EndTextCommandBusyString(0)
end
Utility.StopBusySpinner = function()
if BusyspinnerIsOn() then BusyspinnerOff() end
end
Utility.CreateProp = function(model, coords, heading, networked)
if networked == nil then networked = true end
Utility.LoadModel(model)
if not HasModelLoaded(model) then return Prints.error("Model Has Not Loaded") end
local propEntity = CreateObject(model, coords.x, coords.y, coords.z, networked, false, false)
SetEntityHeading(propEntity, heading)
SetModelAsNoLongerNeeded(model)
return propEntity
end
Utility.CreateBlip = function(coords, sprite, color, scale, label, shortRange)
local blip = AddBlipForCoord(coords.x, coords.y, coords.z)
SetBlipSprite(blip, sprite or 8)
SetBlipColour(blip, color or 3)
SetBlipScale(blip, scale or 0.8)
SetBlipAsShortRange(blip, shortRange)
AddTextEntry(label, label)
BeginTextCommandSetBlipName(label)
EndTextCommandSetBlipName(blip)
table.insert(blipIDs, blip)
return blip
end
Utility.RemoveBlip = function(blip)
local success = false
for i, storedBlip in ipairs(blipIDs) do
if storedBlip == blip then
RemoveBlip(blip)
table.remove(blipIDs, i)
success = true
break
end
end
return success
end
Utility.LoadModel = function(model)
if type(model) ~= 'number' then model = joaat(model) end
if not IsModelValid(model) and not IsModelInCdimage(model) then return false end
RequestModel(model)
local count = 0
while not HasModelLoaded(model) and count < 30000 do
Wait(0)
count = count + 1
end
return HasModelLoaded(model)
end
Utility.CreatePed = function(model, coords, heading, networked, clothing)
if networked == nil then networked = true end
Utility.LoadModel(model)
if not HasModelLoaded(model) then return Prints.error("Model Has Not Loaded") end
local spawnedEntity = CreatePed(0, model, coords.x, coords.y, coords.z, heading, networked, false)
if clothing then
for componentID, v in pairs(clothing) do
SetPedComponentVariation(spawnedEntity, componentID, v[1], v[2], 0)
end
end
FreezeEntityPosition(spawnedEntity, true)
SetEntityInvincible(spawnedEntity, true)
SetBlockingOfNonTemporaryEvents(spawnedEntity, true)
SetModelAsNoLongerNeeded(model)
table.insert(spawnedPeds, spawnedEntity)
return spawnedEntity
end
Utility.RemovePed = function(entity)
local success = false
DeleteEntity(entity)
for i, storedEntity in ipairs(spawnedPeds) do
if storedEntity == entity then
table.remove(spawnedPeds, i)
success = true
break
end
end
return success
end
Utility.NativeInputMenu = function(text, length)
local maxLength = Math.Clamp(length, 1, 50)
local menutText = text or 'enter text'
AddTextEntry(menutText, menutText)
DisplayOnscreenKeyboard(1, menutText, "", "", "", "", "", maxLength)
while(UpdateOnscreenKeyboard() == 0) do
DisableAllControlActions(0)
Wait(0)
end
if(GetOnscreenKeyboardResult()) then
local result = GetOnscreenKeyboardResult()
return result
end
return false
end
Utility.GetEntitySkinData = function(entity)
local skinData = {}
skinData.clothing = {}
for i = 0, 11 do
skinData.clothing[i] = {GetPedDrawableVariation(entity, i), GetPedTextureVariation(entity, i)}
end
return skinData
end
Utility.SetEntitySkinData = function(entity, skinData)
for i = 0, 11 do
SetPedComponentVariation(entity, i, skinData.clothing[i][1], skinData.clothing[i][2], 0)
end
return true
end
Utility.NativeAlert = function(data)
local message = data.message or 'No message provided'
local coords = data.coords or GetEntityCoords(cache.ped)
local job = data.job
local scale = data.scale or 0.8
local sprite = data.sprite or 1
TriggerServerEvent('community_bridge:server:alert', {message = message, coords = coords, job = job, scale = scale, sprite = sprite})
end
Utility.ReloadSkin = function()
local skinData = Utility.GetEntitySkinData(cache.ped)
Utility.SetEntitySkinData(cache.ped, skinData)
for _, props in pairs(GetGamePool("CObject")) do
if IsEntityAttachedToEntity(cache.ped, props) then
SetEntityAsMissionEntity(props, true, true)
DeleteObject(props)
DeleteEntity(props)
end
end
return true
end
Utility.RestoreAppearance = function(data)
return Utility.SetEntitySkinData(cache.ped, data)
end
Utility.HelpText = function(text, duration)
AddTextEntry(text, text)
BeginTextCommandDisplayHelp(text)
EndTextCommandDisplayHelp(0, false, true, duration or 5000)
end
Utility.NotifyText = function(text)
AddTextEntry(text, text)
SetNotificationTextEntry(text)
DrawNotification(false, true)
end
Utility.TeleportPlayer = function(coords, conditionFunction, afterTeleportFunction)
if conditionFunction ~= nil then
if not conditionFunction() then
return
end
end
DoScreenFadeOut(2500)
Wait(2500)
SetEntityCoords(cache.ped, coords.x, coords.y, coords.z, false, false, false, false)
if coords.w then
SetEntityHeading(cache.ped, coords.w)
end
FreezeEntityPosition(cache.ped, true)
local count = 0
while not HasCollisionLoadedAroundEntity(cache.ped) and count <= 30000 do
RequestCollisionAtCoord(coords.x, coords.y, coords.z)
Wait(0)
count = count + 1
end
FreezeEntityPosition(cache.ped, false)
DoScreenFadeIn(1000)
if afterTeleportFunction ~= nil then
afterTeleportFunction()
end
end
Utility.GetEntityHashFromModel = function(model)
if type(model) ~= 'number' then model = joaat(model) end
return model
end
Utility.GetClosestPlayer = function(coords, distanceScope, includeMe)
local players = GetActivePlayers()
local closestPlayer = 0
local selfPed = cache.ped
local selfCoords = coords or GetEntityCoords(cache.ped)
local closestDistance = distanceScope or 5
for _, player in ipairs(players) do
local playerPed = GetPlayerPed(player)
if includeMe or playerPed ~= selfPed then
local playerCoords = GetEntityCoords(playerPed)
local distance = #(selfCoords - playerCoords)
if closestDistance == -1 or distance < closestDistance then
closestPlayer = player
closestDistance = distance
end
end
end
return closestPlayer, closestDistance, GetPlayerServerId(closestPlayer)
end
AddEventHandler('onResourceStop', function(resource)
if resource ~= GetCurrentResourceName() then
for _, blip in pairs(blipIDs) do
if DoesBlipExist(blip.id) then
RemoveBlip(blip.id)
end
end
for _, ped in pairs(spawnedPeds) do
if DoesEntityExist(ped) then
DeleteEntity(ped)
end
end
end
end)
RegisterNetEvent('community_bridge:client:alert', function(data)
local blip = Utility.CreateBlip(data.coords, data.sprite, 3, data.scale, data.message, true)
SetTimeout(40000, function()
Utility.RemoveBlip(blip)
end)
end)
+107
View File
@@ -0,0 +1,107 @@
local activePlacementProp = nil
lib.locale()
-- Object placer --
local placementText = {
locale('place_object'),
locale('place_object_place'),
locale('place_object_cancel'),
locale('place_object_scroll_up'),
locale('place_object_scroll_down')
}
local function finishPlacing()
Bridge.notify.HideHelpText()
if activePlacementProp == nil then return end
DeleteObject(activePlacementProp)
activePlacementProp = nil
end
Utility.PlaceObject = function(object, distance, snapToGround, allowedMats, offset)
if activePlacementProp then return end
if not object then lib.print.error('no_prop_defined') end
local propObject = type(object) == 'string' and joaat(object) or object
local heading = 0.0
local checkDist = distance or 10.0
Utility.LoadModel(propObject)
activePlacementProp = CreateObject(propObject, 1.0, 1.0, 1.0, false, true, true)
SetModelAsNoLongerNeeded(propObject)
SetEntityAlpha(activePlacementProp, 150, false)
SetEntityCollision(activePlacementProp, false, false)
SetEntityInvincible(activePlacementProp, true)
FreezeEntityPosition(activePlacementProp, true)
Bridge.notify.ShowHelpText(type(placementText) == 'table' and table.concat(placementText) or placementText, {
position = "left-center",
})
local outLine = false
while activePlacementProp do
--local hit, _, coords, _, materialHash = lib.raycast.fromCamera(1, 4)
--local hit, _, coords, _, materialHash = lib.raycast.fromCamera(1, 4, nil)
local hit, _, coords, _, materialHash = lib.raycast.fromCamera(1, 4)
if hit then
if offset then
coords += offset
end
SetEntityCoords(activePlacementProp, coords.x, coords.y, coords.z, false, false, false, false)
local distCheck = #(GetEntityCoords(cache.ped) - coords)
SetEntityHeading(activePlacementProp, heading)
if snapToGround then
PlaceObjectOnGroundProperly(activePlacementProp)
end
if outLine then
outLine = false
SetEntityDrawOutline(activePlacementProp, false)
end
if (allowedMats and not allowedMats[materialHash]) or distCheck >= checkDist then
if not outLine then
outLine = true
SetEntityDrawOutline(activePlacementProp, true)
end
end
if IsControlJustReleased(0, 38) then
if not outLine and (not allowedMats or allowedMats[materialHash]) and distCheck < checkDist then
finishPlacing()
return coords, heading
end
end
if IsControlJustReleased(0, 73) then
finishPlacing()
return nil, nil
end
if IsControlJustReleased(0, 14) then
heading = heading + 5
if heading > 360 then heading = 0.0 end
end
if IsControlJustReleased(0, 15) then
heading = heading - 5
if heading < 0 then
heading = 360.0
end
end
end
end
end
Utility.StopPlacing = function()
if not activePlacementProp then return end
finishPlacing()
end
-- This is derrived and slightly altered from its creator and licensed under GPL-3.0 license Author:Zoo, the original is located here https://github.com/Renewed-Scripts/Renewed-Lib/tree/main
@@ -0,0 +1,38 @@
VersionCheck = {}
function VersionCheck.VersionChecker(repoPath)
local resource = repoPath:match("([^/]+)$")
if not resource then return print('^1Invalid repository format. Expected format: "username/reponame"^0') end
local version = GetResourceMetadata(resource, "version", 0)
if not version then return print(('^1Unable to determine current resource version for %s ^0'):format(resource)) end
version = version:match('%d+%.%d+%.%d+')
if not version then return print(('^1Invalid version format for %s ^0'):format(resource)) end
local username, reponame = repoPath:match("([^/]+)/([^/]+)")
if not username or not reponame then return print('^1Invalid repository format. Expected format: "username/reponame"^0') end
PerformHttpRequest(('https://api.github.com/repos/%s/%s/releases/latest'):format(username, reponame), function(status, response)
local failure = ('^1Unable locate github repo for resource %s ^0'):format(resource)
if status ~= 200 then return print(failure) end
response = json.decode(response)
if response.prerelease then return print(failure) end
local latest = response.tag_name:match('%d+%.%d+%.%d+')
if not latest then return print(failure) end
if latest == version then return print(('^2 %s is on the latest version.^0'):format(resource)) end
local currentVersion, latestVersion = version:gsub('%D', ''), latest:gsub('%D', '')
if currentVersion < latestVersion then
return print(('^1An update is available for %s (current version: %s)\r\n - ^5Please download the latest version from the GitHub release page.^7\r\n%s'):format(resource, version, response.html_url))
end
end, 'GET')
end
AddEventHandler('onResourceStart', function(resourceName)
if GetCurrentResourceName() ~= resourceName then return end
VersionCheck.VersionChecker("MrNewb/community_bridge")
end)
+50
View File
@@ -0,0 +1,50 @@
Logger = {}
local WebhookURL = BridgeServerConfig.WebhookURL
local LogoForEmbed = BridgeServerConfig.WebhookImage
Logger.SendLog = function(src, message)
if not src or not message then return end
if BridgeServerConfig.LogSystem == "builtin" then
PerformHttpRequest(WebhookURL, function(err, text, headers) end, 'POST', json.encode(
{
username = "Community_Bridge's Logger",
avatar_url = 'https://cdn.discordapp.com/avatars/299410129982455808/31ce635662206e8bd0132c34ce9ce683?size=1024',
embeds = {
{
color = "15769093",
title = GetCurrentResourceName(),
url = 'https://discord.gg/wsPAK5mEPg',
--description = message,
thumbnail = { url = LogoForEmbed },
fields = {
{
name = '**Player ID**',
value = src,
inline = true,
},
{
name = '**Player Identifier**',
value = Framework.GetPlayerIdentifier(src),
inline = true,
},
{
name = 'Log Message',
value = "```"..message.."```",
inline = false,
},
},
timestamp = os.date('!%Y-%m-%dT%H:%M:%S'),
footer = {
text = "Community_Bridge | "..GetCurrentResourceName(),
icon_url = 'https://cdn.discordapp.com/avatars/299410129982455808/31ce635662206e8bd0132c34ce9ce683?size=1024',
},
}
}
}), { ['Content-Type']= 'application/json' })
elseif BridgeServerConfig.LogSystem == "qb" then
return TriggerEvent('qb-log:server:CreateLog', GetCurrentResourceName(), GetCurrentResourceName(), 'green', message)
elseif BridgeServerConfig.LogSystem == "ox" then
return exports.ox_lib:logger(src, GetCurrentResourceName(), message)
end
end
+68
View File
@@ -0,0 +1,68 @@
LootTables = {}
LootTables.RegisterLootTable = function(name, items)
local repackedTable = {}
for k, v in pairs(items) do
table.insert(repackedTable, {
name = k,
min = v.min,
max = v.max,
chance = v.chance,
tier = v.tier,
item = v.item,
metadata = v.metadata
})
end
LootTables[name] = repackedTable
return LootTables[name]
end
LootTables.GetLootTable = function(name)
assert(name, "No Name Passed For Loot Table")
return LootTables[name] or {}
end
LootTables.GetRandomItem = function(name, tier, randomNumber)
assert(name, "No Name Passed For Loot Table")
if tier == nil then tier = 1 end
local lootTable = LootTables[name] or {}
math.randomseed(GetGameTimer())
local chance = randomNumber or math.random(1, 100)
for _, v in pairs(lootTable) do
if v.chance <= chance and tier == v.tier then
return { item = v.item, metadata = v.metadata, count = math.random(v.min, v.max), tier = v.tier, chance = v.chance}
end
end
end
LootTables.GetRandomItems = function(name, tier, randomNumber)
assert(name, "No Name Passed For Loot Table")
if tier == nil then tier = 1 end
local lootTable = LootTables.GetLootTable(name)
math.randomseed(GetGameTimer())
local chance = randomNumber or math.random(1, 100)
local items = {}
for _, v in pairs(lootTable) do
if v.chance <= chance and tier == v.tier then
table.insert(items,{item = v.item, metadata = v.metadata, count = math.random(v.min, v.max), tier = v.tier, chance = v.chance})
end
end
return items
end
LootTables.GetRandomItemsWithLimit = function(name, tier, randomNumber)
assert(name, "No Name Passed For Loot Table")
if tier == nil then tier = 1 end
local lootTable = LootTables.GetLootTable(name)
math.randomseed(GetGameTimer())
local chance = randomNumber or math.random(1, 100)
local items = {}
for k = #lootTable, 1, -1 do
local v = lootTable[k]
if chance <= v.chance and tier == v.tier then
table.insert(items, {v.item, v.metadata, math.random(v.min, v.max), v.tier, v.chance})
table.remove(lootTable, k)
end
end
return items
end
@@ -0,0 +1,6 @@
RegisterServerEvent("community_bridge:server:alert", function(data)
local playersByJob = Framework.GetPlayersByJob(data.job)
for _, src in pairs(playersByJob) do
TriggerClientEvent("community_bridge:client:alert", src, data)
end
end)
+10
View File
@@ -0,0 +1,10 @@
if GetResourceState('qb-weathersync') ~= 'started' then return end
Weather = {}
Weather.ToggleSync = function(toggle)
if toggle then
TriggerEvent("qb-weathersync:client:EnableSync")
else
TriggerEvent("qb-weathersync:client:DisableSync")
end
end
@@ -0,0 +1,6 @@
if GetResourceState('Renewed-Weathersync') ~= 'started' then return end
Weather = {}
Weather.ToggleSync = function(toggle)
LocalPlayer.state.syncWeather = toggle
end
+10
View File
@@ -0,0 +1,10 @@
if GetResourceState('qb-weathersync') ~= 'started' then return end
Weather = {}
Weather.ToggleSync = function(toggle)
if toggle then
TriggerEvent("qb-weathersync:client:EnableSync")
else
TriggerEvent("qb-weathersync:client:DisableSync")
end
end
+11
View File
@@ -0,0 +1,11 @@
BridgeClientConfig = {}
BridgeClientConfig.NotifySystem = "ox" -- Change this to your notification system (ox/qb/esx?)
BridgeClientConfig.ZoneSystem = "ox" -- Change this to your dialog system (ox/poly)
BridgeClientConfig.InputSystem = "ox" -- Change this to your Input system (ox/qb)
BridgeClientConfig.MenuSystem = "ox" -- Change this to your Menu system (ox/qb)
BridgeClientConfig.ProgressBar = "ox" -- Change this to your preferred progress bar (ox/qb)
BridgeClientConfig.DebugLevel = 3 -- Change this to your Debug level, 1 for none, 2 for some, 3 for all data
BridgeClientConfig.ShowHelpText = "ox" --
Require("init.lua", "ox_lib")
return BridgeClientConfig
+8
View File
@@ -0,0 +1,8 @@
BridgeServerConfig = {}
BridgeServerConfig.LogSystem = "builtin" -- "builtin", "qb", "ox"
BridgeServerConfig.WebhookURL = "PUT_WEBHOOK_URL_HERE"
BridgeServerConfig.WebhookImage = "https://cdn.discordapp.com/avatars/299410129982455808/31ce635662206e8bd0132c34ce9ce683?size=1024"
BridgeServerConfig.MaxInventorySlots = 50
Require("init.lua", "ox_lib")
return BridgeServerConfig
+5
View File
@@ -0,0 +1,5 @@
BridgeSharedConfig = {}
BridgeSharedConfig.Lang = "auto" -- Change this to your preferred language (must match the locale file name ex. en or fr etc)
BridgeSharedConfig.DebugLevel = 3 -- Change this to your Debug level, 1 for none, 2 for some, 3 for all data
return BridgeSharedConfig
+25
View File
@@ -0,0 +1,25 @@
importing resource in shared -- should be an option, exports could be primary use but importing in shared should be available
Locales do not seem to work using the export method.
Serversided stashes are busted using internal method -- may be best to rework this logic https://github.com/Mustachedom/md-stashes/blob/main/server/server.lua
-------[[ Crowley ]]--------
^ Locales 1-1 with ox.
We need a simple easy to use locale system. Ox does it in a single line, we need the same otherwise why would they use it.
^ Simpler Init method.
The tables are the only approach I could think of for this while having fallback functions
fallback functions are **required**.
current location -- community_bridge\modules\initialize
----[[ Newb ]]----
1.8.25
+22
View File
@@ -0,0 +1,22 @@
Ids = {}
function Ids.CreateUniqueId(tbl, len, pattern) -- both optional
tbl = tbl or {} -- table to check uniqueness. Ids to check against must be the key to the tables value
len = len or 8
local id = ""
for i = 1, len do
local char = ""
if pattern then
char = pattern:sub(math.random(1, #pattern), math.random(1, #pattern))
else
char = math.random(1, 2) == 1 and string.char(math.random(65, 90)) or math.random(0, 9) -- CAP letter and number
end
id = id .. char
end
if tbl[id] then
return Ids.CreateUniqueId(tbl, len, pattern)
end
return id
end
return Ids
Loaded 100 of 104 files, more files were not shown because too many files have changed in this diff. Show more