Created
August 20, 2024 15:48
-
-
Save solareon/7133a635fa56191a3d5a17a696a1abb8 to your computer and use it in GitHub Desktop.
qb-inventory to ox_inventory conversion code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
convertDatabase = function() | |
local Items = {} | |
local function newItem(data) | |
data.weight = data.weight or 0 | |
Items[data.name] = data | |
end | |
for type, data in pairs(lib.load('data.weapons')) do | |
for k, v in pairs(data) do | |
v.name = k | |
v.close = type == 'Ammo' and true or false | |
v.weight = v.weight or 0 | |
if type == 'Weapons' then | |
---@cast v OxWeapon | |
v.model = v.model or k -- actually weapon type or such? model for compatibility | |
v.hash = joaat(v.model) | |
v.stack = v.throwable and true or false | |
v.durability = v.durability or 0.05 | |
v.weapon = true | |
else | |
v.stack = true | |
end | |
v[type == 'Ammo' and 'ammo' or type == 'Components' and 'component' or type == 'Tints' and 'tint' or 'weapon'] = true | |
if isServer then v.client = nil else | |
v.count = 0 | |
v.server = nil | |
local clientData = v.client | |
if clientData?.image then | |
clientData.image = setImagePath(clientData.image) | |
end | |
end | |
ItemList[k] = v | |
end | |
end | |
for k, v in pairs(lib.load('data.items')) do | |
v.name = k | |
local success, response = pcall(newItem, v) | |
if not success then | |
warn(('An error occurred while creating item "%s" callback!\n^1SCRIPT ERROR: %s^0'):format(k, response)) | |
end | |
end | |
Items.cash = Items.money | |
local function Items.Metadata(inv, item, metadata, count) | |
if type(inv) ~= 'table' then inv = Inventory(inv) end | |
if not item.weapon then metadata = not metadata and {} or type(metadata) == 'string' and {type=metadata} or metadata end | |
if not count then count = 1 end | |
---@cast metadata table<string, any> | |
if item.weapon then | |
if type(metadata) ~= 'table' then metadata = {} end | |
if not metadata.durability then metadata.durability = 100 end | |
if not metadata.ammo and item.ammoname then metadata.ammo = 0 end | |
if not metadata.components then metadata.components = {} end | |
if metadata.registered ~= false and (metadata.ammo or item.name == 'WEAPON_STUNGUN') then | |
local registered = type(metadata.registered) == 'string' and metadata.registered or inv?.player?.name | |
metadata.registered = registered | |
metadata.serial = GenerateSerial(metadata.serial) | |
end | |
if item.hash == `WEAPON_PETROLCAN` or item.hash == `WEAPON_HAZARDCAN` or item.hash == `WEAPON_FERTILIZERCAN` or item.hash == `WEAPON_FIREEXTINGUISHER` then | |
metadata.ammo = metadata.durability | |
end | |
else | |
local container = Items.containers[item.name] | |
if container then | |
count = 1 | |
metadata.container = metadata.container or GenerateText(3)..os.time() | |
metadata.size = container.size | |
elseif not next(metadata) then | |
if item.name == 'identification' then | |
count = 1 | |
metadata = { | |
type = inv.player.name, | |
description = locale('identification', (inv.player.sex) and locale('male') or locale('female'), inv.player.dateofbirth) | |
} | |
elseif item.name == 'garbage' then | |
local trashType = trash[math.random(1, #trash)] | |
metadata.image = trashType.image | |
metadata.weight = trashType.weight | |
metadata.description = trashType.description | |
end | |
end | |
if not metadata.durability then | |
metadata = setItemDurability(ItemList[item.name], metadata) | |
end | |
end | |
if count > 1 and not item.stack then | |
count = 1 | |
end | |
local response = TriggerEventHooks('createItem', { | |
inventoryId = inv and inv.id, | |
metadata = metadata, | |
item = item, | |
count = count, | |
}) | |
if type(response) == 'table' then | |
metadata = response | |
end | |
if metadata.imageurl and Utils.IsValidImageUrl then | |
if Utils.IsValidImageUrl(metadata.imageurl) then | |
Utils.DiscordEmbed('Valid image URL', ('Created item "%s" (%s) with valid url in "%s".\n%s\nid: %s\nowner: %s'):format(metadata.label or item.label, item.name, inv.label, metadata.imageurl, inv.id, inv.owner, metadata.imageurl), metadata.imageurl, 65280) | |
else | |
Utils.DiscordEmbed('Invalid image URL', ('Created item "%s" (%s) with invalid url in "%s".\n%s\nid: %s\nowner: %s'):format(metadata.label or item.label, item.name, inv.label, metadata.imageurl, inv.id, inv.owner, metadata.imageurl), metadata.imageurl, 16711680) | |
metadata.imageurl = nil | |
end | |
end | |
return metadata, count | |
end | |
local function slotWeight(item, slot, ignoreCount) | |
local weight = ignoreCount and item.weight or item.weight * (slot.count or 1) | |
if not slot.metadata then slot.metadata = {} end | |
if item.ammoname and slot.metadata.ammo then | |
local ammoWeight = Items(item.ammoname)?.weight | |
if ammoWeight then | |
weight += (ammoWeight * slot.metadata.ammo) | |
end | |
end | |
if item.hash == `WEAPON_PETROLCAN` then | |
weight += 15000 * (slot.metadata.ammo / 100) | |
end | |
if slot.metadata.components then | |
for i = #slot.metadata.components, 1, -1 do | |
local componentWeight = Items(slot.metadata.components[i])?.weight | |
if componentWeight then | |
weight += componentWeight | |
end | |
end | |
end | |
if slot.metadata.weight then | |
weight += ignoreCount and slot.metadata.weight or (slot.metadata.weight * (slot.count or 1)) | |
end | |
return weight | |
end | |
local function convertInventory(playerId, items) | |
if type(items) == 'table' then | |
local returnData, totalWeight = table.create(#items, 0), 0 | |
local slot = 0 | |
for _, data in pairs(items) do | |
local item = Items(data.name) | |
if item?.name then | |
local metadata, count = Items.Metadata(playerId, item, data.info, data.amount or data.count or 1) | |
local weight = slotWeight(item, { count = count, metadata = metadata }) | |
totalWeight += weight | |
slot += 1 | |
returnData[slot] = { | |
name = item.name, | |
label = item.label, | |
weight = weight, | |
slot = slot, | |
count = count, | |
description = | |
item.description, | |
metadata = metadata, | |
stack = item.stack, | |
close = item.close | |
} | |
end | |
end | |
return returnData, totalWeight | |
end | |
end | |
local users = MySQL.query.await('SELECT citizenid, inventory, money FROM players') | |
if not users then return end | |
local count = 0 | |
local parameters = {} | |
for i = 1, #users do | |
local inventory, slot = {}, 0 | |
local user = users[i] | |
local items = user.inventory and json.decode(user.inventory) or {} | |
local accounts = user.money and json.decode(user.money) or {} | |
for k, v in pairs(accounts) do | |
if type(v) == 'table' then break end | |
if k == 'cash' then k = 'money' end | |
if server.accounts[k] and Items(k) and v > 0 then | |
slot += 1 | |
inventory[slot] = {slot=slot, name=k, count=v} | |
end | |
end | |
local shouldConvert = false | |
for _, v in pairs(items) do | |
if Items(v?.name) then | |
slot += 1 | |
inventory[slot] = {slot=slot, name=v.name, count=v.amount, metadata = type(v.info) == 'table' and v.info or {}} | |
if v.type == "weapon" then | |
inventory[slot].metadata.durability = v.info.quality or 100 | |
inventory[slot].metadata.ammo = v.info.ammo or 0 | |
inventory[slot].metadata.components = {} | |
inventory[slot].metadata.serial = v.info.serie or lib.string.random('111111AAA111111') | |
inventory[slot].metadata.quality = nil | |
end | |
end | |
shouldConvert = v.amount and true | |
end | |
if shouldConvert then | |
count += 1 | |
parameters[count] = { 'UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(inventory), user.citizenid } } | |
end | |
end | |
if count > 0 then | |
print(('^2[info]^7 Converting %s user inventories to new data format'):format(count)) | |
if not MySQL.transaction.await(parameters) then | |
return Print('^1[error]^7 An error occurred while converting player inventories') | |
end | |
Wait(100) | |
else | |
print('^2[info]^7 No user inventories to convert. Skipping..') | |
end | |
local plates = MySQL.query.await('SELECT plate, citizenid FROM player_vehicles') | |
if plates then | |
for i = 1, #plates do | |
plates[plates[i].plate] = plates[i].citizenid | |
end | |
local oldqbdumpsterfire, trunk = pcall(MySQL.query.await, 'SELECT plate, items FROM trunkitems') | |
if oldqbdumpsterfire and trunk then | |
table.wipe(parameters) | |
count = 0 | |
local vehicles = {} | |
for _, v in pairs(trunk) do | |
local owner = plates[v.plate] | |
if owner then | |
if not vehicles[owner] then | |
vehicles[owner] = {} | |
end | |
if not vehicles[owner][v.plate] then | |
local items = json.decode(v.items) or {} | |
local inventory, slot = {}, 0 | |
for _, v in pairs(items) do | |
if Items(v?.name) then | |
slot += 1 | |
inventory[slot] = {slot=slot, name=v.name, count=v.amount, metadata = type(v.info) == 'table' and v.info or {}} | |
if v.type == "weapon" then | |
inventory[slot].metadata.durability = v.info.quality or 100 | |
inventory[slot].metadata.ammo = v.info.ammo or 0 | |
inventory[slot].metadata.components = {} | |
inventory[slot].metadata.serial = v.info.serie or lib.string.random('111111AAA111111') | |
inventory[slot].metadata.quality = nil | |
end | |
end | |
end | |
vehicles[owner][v.plate] = true | |
count += 1 | |
parameters[count] = { 'UPDATE player_vehicles SET trunk = ? WHERE plate = ? AND citizenid = ?', { json.encode(inventory), v.plate, owner } } | |
end | |
end | |
end | |
print(('^2[info]^7 Moving ^3%s^0 trunks to the player_vehicles table'):format(count)) | |
if count > 0 then | |
if not MySQL.transaction.await(parameters) then | |
return print('An error occurred while converting trunk inventories') | |
end | |
Wait(100) | |
end | |
end | |
local glovebox = oldqbdumpsterfire and MySQL.query.await('SELECT plate, items FROM gloveboxitems') | |
if glovebox then | |
table.wipe(parameters) | |
count = 0 | |
local vehicles = {} | |
for _, v in pairs(glovebox) do | |
local owner = plates[v.plate] | |
if owner then | |
if not vehicles[owner] then | |
vehicles[owner] = {} | |
end | |
if not vehicles[owner][v.plate] then | |
local items = json.decode(v.items) or {} | |
local inventory, slot = {}, 0 | |
for _, v in pairs(items) do | |
if Items(v?.name) then | |
slot += 1 | |
inventory[slot] = {slot=slot, name=v.name, count=v.amount, metadata = type(v.info) == 'table' and v.info or {}} | |
if v.type == "weapon" then | |
inventory[slot].metadata.durability = v.info.quality or 100 | |
inventory[slot].metadata.ammo = v.info.ammo or 0 | |
inventory[slot].metadata.components = {} | |
inventory[slot].metadata.serial = v.info.serie or lib.string.random() | |
inventory[slot].metadata.quality = nil | |
end | |
end | |
end | |
vehicles[owner][v.plate] = true | |
count += 1 | |
parameters[count] = { 'UPDATE player_vehicles SET glovebox = ? WHERE plate = ? AND citizenid = ?', { json.encode(inventory), v.plate, owner } } | |
end | |
end | |
end | |
print(('^2[info]^7 Moving ^3%s^0 gloveboxes to the player_vehicles table'):format(count)) | |
if count > 0 then | |
if not MySQL.transaction.await(parameters) then | |
return print('^1[error]^7 An error occurred while converting glovebox inventories') | |
end | |
end | |
end | |
end | |
local qbEvidence = MySQL.query.await("SELECT stash, items FROM stashitems WHERE stash LIKE '% | Drawer%'") | |
if qbEvidence then | |
table.wipe(parameters) | |
count = 0 | |
local oxEvidence = {} | |
for i = 1, #qbEvidence do | |
local qbStash = qbEvidence[i] | |
local name = 'evidence-'..qbStash.stash:sub(12) | |
local items = convertInventory(nil, (qbStash.items and json.decode(qbStash.items) or {})) | |
--- evidence numbers can be shared between locations, so need to maintain map and merge. | |
if oxEvidence[name] then | |
for k = 1, #items do | |
oxEvidence[name][#oxEvidence[name]+1] = items[k] | |
end | |
else | |
oxEvidence[name] = items | |
end | |
end | |
for name, items in pairs(oxEvidence) do | |
count += 1 | |
parameters[count] = { "INSERT INTO ox_inventory (owner, name, data) VALUES ('', ?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name), data = VALUES(data)", { | |
name, json.encode(items) | |
}} | |
end | |
print(('^2[info]^7 Creating ^3%s^0 evidence lockers from ^3%s^0 lockers by merging duplicate locker numbers'):format(count, #qbEvidence)) | |
if count > 0 then | |
if not MySQL.transaction.await(parameters) then | |
return print('^1[error]^7 An error occurred while converting evidence lockers') | |
end | |
end | |
end | |
print('^2[info]^7 Successfully converted user and vehicle inventories') | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
An incomplete fragment to convert old qb-inv format to new ox_inv format. Doesn't work due to multiple external functions missing.