legacy-lib
Integration
Exports, events, and code for consuming legacy-lib from other resources.
Integration
All integration happens through FiveM exports on legacy-lib. Add legacy-lib (and ox_lib, oxmysql) as dependencies of your resource's fxmanifest.lua and ensure it starts after legacy-lib.
Shared / branding exports
-- any file (shared)
local name = exports['legacy-lib']:moduleName()
local color = exports['legacy-lib']:GetAccentColor()
local grad = exports['legacy-lib']:GetAccentGradient() -- { from, via, to, angle, css }
local logo = exports['legacy-lib']:GetLogo() -- nui:// path or nil
local srv = exports['legacy-lib']:server()
Locale (server or client, put in your resource's own boot file)
local Locale = exports['legacy-lib']:GetLocale(GetCurrentResourceName())
-- Requires locales/en.json (or other) to exist inside YOUR OWN resource, not legacy-lib
Discord webhooks (server file, e.g. server/main.lua)
exports['legacy-lib']:SendWebhook(
webhookUrl, -- '' or nil silently disables the webhook, no error
'Bill Created',
'A new bill was issued to John Doe for $500',
'#4ADE80',
{ { name = 'Amount', value = '$500', inline = true } }
)
Version checking (server file, run on resource start)
exports['legacy-lib']:CheckVersion(GetCurrentResourceName(), Config.Version)
File-backed JSON store (server-only, e.g. server/store.lua)
local Store = exports['legacy-lib']:Store()
local PATH = 'data/locations.json'
local data, reason = Store.Read(GetCurrentResourceName(), PATH)
if not data and reason == 'absent' then
data = importFromSql()
Store.Write(GetCurrentResourceName(), PATH, data)
end
-- mutate data ...
Store.Write(GetCurrentResourceName(), PATH, data)
Or use the one-shot migration helper:
local data, migrated = Store.ReadOrMigrate(GetCurrentResourceName(), 'data/rigs.json', {}, function()
return MySQL.query.await('SELECT * FROM legacy_rigs')
end)
Always pass GetCurrentResourceName() (your own resource), never 'legacy-lib' — Store reads/writes relative to the resource name you provide.
Banking abstraction (server file)
Banking.AddAccountMoney('police', 500, 'Evidence locker fee')
local bal = Banking.GetAccountMoney('police')
Banking.RemoveAccountMoney('police', 200, 'Payout')
local acct = Banking.GetSocietyAccount('police') -- { balance, iban, ibanFormatted, accountNumber, name }
local result = Banking.SocietyTransfer(src, 'police', { amount = 100, recipient = 'IBAN...', memo = 'Payroll' })
SocietyTransfer and real GetSocietyAccount data are only fully supported on the legacy-banking bridge.
Framework abstraction (server or client file, depending on function)
local identifier = Framework.GetPlayerIdentifier(src)
local firstName, lastName = Framework.GetPlayerName(src)
local jobData = Framework.GetPlayerJobData(src) -- { jobName, jobLabel, gradeName, gradeLabel, gradeRank, boss, onDuty }
local balance = Framework.GetAccountBalance(src, 'bank')
Framework.AddAccountBalance(src, 'bank', 500)
Framework.SetPlayerJob(src, 'police', 2)
local employees = Framework.GetEmployees('police')
Inventory abstraction (server file)
print(Inventory.GetResourceName()) -- 'ox_inventory' | 'qb-inventory' | 'qs-inventory' | 'default'
local ok = Inventory.AddItem(src, 'water', 1)
Inventory.RegisterUsableItem('water', function(source, item, itemData)
-- itemData shape depends on the underlying bridge
end)
Stash functions (RegisterStash, SearchStash, AddStashItem, RemoveStashItem) only exist on the ox_inventory bridge.
Client-side Target and Inventory (client file)
local Target = exports['legacy-lib']:Target()
local Inventory = exports['legacy-lib']:Inventory() -- global var is InventoryClient internally
Target.AddLocalEntity(entityHandle, {
{ name = 'talk', label = 'Talk', icon = 'fas fa-comment', onSelect = function(entity) end }
})
Inventory.OpenStash('shop_stash_1')
Events
onResourceStart(resourceName) is used internally by the banking bridges (modules/banking/qb-banking.lua, Renewed-Banking.lua, legacy-banking.lua) to re-bind their Banking.* implementation once their target banking resource actually starts (important since e.g. legacy-banking depends on legacy-lib and therefore always starts after it). This is not intended to be hooked by consuming resources directly — no public payload/API beyond resourceName is documented for external use.
Extending a bridge
To add support for a framework/banking/inventory/target system not already covered, add a new file in the matching modules/<category>/ folder, guard it with a GetResourceState(...) == 'started' check, and implement the relevant functions on the shared global table:
-- modules/framework/my-framework.lua
if GetResourceState('my-framework') ~= 'started' then return end
Framework = Framework or {}
Framework.GetResourceName = function() return 'my-framework' end
Framework.GetPlayerIdentifier = function(src) --[[ ... ]] end
-- override remaining Framework.* functions as needed