AddFramework {
'myframework',
{
benchOptions = {
type = BenchTypes.ITEM, -- BenchTypes.ITEM | BenchTypes.PURCHASE
},
--[[
items - Get the items to use for the framework.
Use either
- the types specified in config.lua
- the nameGXT value which you can find for the components and tints in src/weapons.json
to set the items
These items will be overrided by some inventories, like ox_inventory
]]
items = {
components = {
default = 'weapon_component',
clip = 'clip_attachment',
suppressor = 'suppressor_attachment',
flashlight = 'flashlight_attachment',
compensator = 'compensator_attachment',
grip = 'grip_attachment',
small_scope = 'smallscope_attachment',
scope = 'medscope_attachment',
large_scope = 'largescope_attachment',
holo_scope = 'holoscope_attachment',
thermal_scope = 'thermalscope_attachment',
night_vision_scope = 'nvscope_attachment',
mounted_scope = 'medscope_attachment',
advanced_scope = 'advscope_attachment',
shell = 'shell_attachment',
['WCT_VAR_GOLD'] = 'luxuryfinish_attachment',
['WCT_CAMO_1'] = 'digicamo_attachment',
['WCT_CAMO_2'] = 'brushcamo_attachment',
['WCT_CAMO_3'] = 'woodcamo_attachment',
['WCT_CAMO_4'] = 'skullcamo_attachment',
['WCT_CAMO_5'] = 'sessantacamo_attachment',
['WCT_CAMO_6'] = 'perseuscamo_attachment',
['WCT_CAMO_7'] = 'leopardcamo_attachment',
['WCT_CAMO_8'] = 'zebracamo_attachment',
['WCT_CAMO_9'] = 'geocamo_attachment',
['WCT_CAMO_10'] = 'boomcamo_attachment',
['WCT_CAMO_IND'] = 'patriotcamo_attachment',
['WCT_MUZZ1'] = 'flat_muzzle_brake',
['WCT_MUZZ2'] = 'tactical_muzzle_brake',
['WCT_MUZZ3'] = 'fat_end_muzzle_brake',
['WCT_MUZZ4'] = 'precision_muzzle_brake',
['WCT_MUZZ5'] = 'heavy_duty_muzzle_brake',
['WCT_MUZZ6'] = 'slanted_muzzle_brake',
['WCT_MUZZ7'] = 'split_end_muzzle_brake',
['WCT_MUZZ8'] = 'squared_muzzle_brake',
['WCT_MUZZ9'] = 'bellend_muzzle_brake',
},
tints = {
default = 'tint_component',
['WM_TINT1'] = 'weapontint_1',
['WM_TINT2'] = 'weapontint_2',
['WM_TINT3'] = 'weapontint_3',
['WM_TINT4'] = 'weapontint_4',
['WM_TINT5'] = 'weapontint_5',
['WM_TINT6'] = 'weapontint_6',
['WM_TINT7'] = 'weapontint_7',
['WCT_TINT_0'] = 'weapontint_mk2_0',
['WCT_TINT_1'] = 'weapontint_mk2_1',
['WCT_TINT_2'] = 'weapontint_mk2_2',
['WCT_TINT_3'] = 'weapontint_mk2_3',
['WCT_TINT_4'] = 'weapontint_mk2_4',
['WCT_TINT_5'] = 'weapontint_mk2_5',
['WCT_TINT_6'] = 'weapontint_mk2_6',
['WCT_TINT_7'] = 'weapontint_mk2_7',
['WCT_TINT_8'] = 'weapontint_mk2_8',
['WCT_TINT_9'] = 'weapontint_mk2_9',
['WCT_TINT_10'] = 'weapontint_mk2_10',
['WCT_TINT_11'] = 'weapontint_mk2_11',
['WCT_TINT_12'] = 'weapontint_mk2_12',
['WCT_TINT_13'] = 'weapontint_mk2_13',
['WCT_TINT_14'] = 'weapontint_mk2_14',
['WCT_TINT_15'] = 'weapontint_mk2_15',
['WCT_TINT_16'] = 'weapontint_mk2_16',
['WCT_TINT_17'] = 'weapontint_mk2_17',
['WCT_TINT_18'] = 'weapontint_mk2_18',
['WCT_TINT_19'] = 'weapontint_mk2_19',
['WCT_TINT_20'] = 'weapontint_mk2_20',
['WCT_TINT_21'] = 'weapontint_mk2_21',
['WCT_TINT_22'] = 'weapontint_mk2_22',
['WCT_TINT_23'] = 'weapontint_mk2_23',
['WCT_TINT_24'] = 'weapontint_mk2_24',
['WCT_TINT_25'] = 'weapontint_mk2_25',
['WCT_TINT_26'] = 'weapontint_mk2_26',
['WCT_TINT_27'] = 'weapontint_mk2_27',
['WCT_TINT_28'] = 'weapontint_mk2_28',
['WCT_TINT_29'] = 'weapontint_mk2_29',
['WCT_TINT_30'] = 'weapontint_mk2_30',
['WCT_TINT_31'] = 'weapontint_mk2_31',
}
},
--[[
prices - Get the prices to use for the framework.
Use either
- the types specified in config.lua
- the nameGXT value which you can find for the components and tints in src/weapons.json
to set the prices
]]
prices = {
components = {
default = 100,
clip = 300,
suppressor = 400,
flashlight = 50,
compensator = 200,
grip = 300,
small_scope = 250,
scope = 300,
large_scope = 350,
holo_scope = 250,
thermal_scope = 250,
night_vision_scope = 400,
mounted_scope = 250,
advanced_scope = 400,
shell = 150,
['WCT_VAR_GOLD'] = 100,
['WCT_CAMO_1'] = 100,
['WCT_CAMO_2'] = 100,
['WCT_CAMO_3'] = 100,
['WCT_CAMO_4'] = 100,
['WCT_CAMO_5'] = 100,
['WCT_CAMO_6'] = 100,
['WCT_CAMO_7'] = 100,
['WCT_CAMO_8'] = 100,
['WCT_CAMO_9'] = 100,
['WCT_CAMO_10'] = 100,
['WCT_CAMO_IND'] = 100,
['WCT_MUZZ1'] = 100,
['WCT_MUZZ2'] = 100,
['WCT_MUZZ3'] = 100,
['WCT_MUZZ4'] = 100,
['WCT_MUZZ5'] = 100,
['WCT_MUZZ6'] = 100,
['WCT_MUZZ7'] = 100,
['WCT_MUZZ8'] = 100,
['WCT_MUZZ9'] = 100,
},
tints = {
default = 100,
['WM_TINT1'] = 100,
['WM_TINT2'] = 100,
['WM_TINT3'] = 100,
['WM_TINT4'] = 100,
['WM_TINT5'] = 100,
['WM_TINT6'] = 100,
['WM_TINT7'] = 100,
['WCT_TINT_0'] = 100,
['WCT_TINT_1'] = 100,
['WCT_TINT_2'] = 100,
['WCT_TINT_3'] = 100,
['WCT_TINT_4'] = 100,
['WCT_TINT_5'] = 100,
['WCT_TINT_6'] = 100,
['WCT_TINT_7'] = 100,
['WCT_TINT_8'] = 100,
['WCT_TINT_9'] = 100,
['WCT_TINT_10'] = 100,
['WCT_TINT_11'] = 100,
['WCT_TINT_12'] = 100,
['WCT_TINT_13'] = 100,
['WCT_TINT_14'] = 100,
['WCT_TINT_15'] = 100,
['WCT_TINT_16'] = 100,
['WCT_TINT_17'] = 100,
['WCT_TINT_18'] = 100,
['WCT_TINT_19'] = 100,
['WCT_TINT_20'] = 100,
['WCT_TINT_21'] = 100,
['WCT_TINT_22'] = 100,
['WCT_TINT_23'] = 100,
['WCT_TINT_24'] = 100,
['WCT_TINT_25'] = 100,
['WCT_TINT_26'] = 100,
['WCT_TINT_27'] = 100,
['WCT_TINT_28'] = 100,
['WCT_TINT_29'] = 100,
['WCT_TINT_30'] = 100,
['WCT_TINT_31'] = 100,
}
},
--[[
inventory - Get the inventory to use for the framework.
]]
inventory = useInventory('ox_inventory', { framework = 'esx' }),
--[[
init - Initialize the framework.
]]
init = function()
end,
--[[
getPlayerIdentifier - Get the player's unique identifier.
@param src number
@return string
]]
getPlayerIdentifier = function(src)
end,
--[[
getAccessIdentifiers - Get the access identifiers, used for checking if a player has access to a bench.
@return table { [string] = string }
]]
getAccessIdentifiers = function()
return {}
end,
--[[
getPlayerAccess - Get the player's access identifiers.
@param src number
@return table { [number] = string }
]]
getPlayerAccess = function(src)
return {}
end,
--[[
canUseEditor - Check if a player can use the editor.
@param src number
@param identifier string
@return boolean
]]
canUseEditor = function(src, identifier)
return IsPlayerAceAllowed(src, 'weaponmodbench.editor') == 1 or IsPlayerAceAllowed(src, 'command.editor') == 1
end,
--[[
onUseBench - Called when a player uses a weapon bench to determine if they have access.
@param src number
@param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
@return table { success = boolean, message = string }
]]
onUseBench = function(src, bench)
return {
success = true
}
end,
--[[
onBuyComponent - Called when a player buys a component for a weapon.
@param src number
@param weapon table { hashKey = string, metadata = table }
@param component table { hashKey = string, price = number, item = string }
@param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
@return table { success = boolean, message = string }
]]
onBuyComponent = function(src, weapon, component, bench)
if not framework.inventory?.buyComponent then
return {
success = true
}
else
return framework.inventory.buyComponent(src, weapon, component)
end
end,
--[[
onEquipComponent - Called when a player equips a component to a weapon.
@param src number
@param weapon table { hashKey = string, metadata = table }
@param component table { hashKey = string, price = number, item = string }
@param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
@return table { success = boolean, message = string }
]]
onEquipComponent = function(src, weapon, component, bench)
if not framework.inventory?.equipComponent then
return {
success = true
}
else
return framework.inventory.equipComponent(src, weapon, component)
end
end,
--[[
onUnequipComponent - Called when a player equips a component to a weapon.
@param src number
@param weapon table { hashKey = string, metadata = table }
@param component table { hashKey = string, price = number, item = string }
@param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
@return table { success = boolean, message = string }
]]
onUnequipComponent = function(src, weapon, component, bench)
if not framework.inventory?.unequipComponent then
return {
success = true
}
else
return framework.inventory.unequipComponent(src, weapon, component)
end
end,
--[[
onBuyTint - Called when a player buys a tint.
@param src number
@param weapon table { hashKey = string, metadata = table }
@param tint table { id = number, price = number, item = string }
@param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
@return table { success = boolean, message = string }
]]
onBuyTint = function(src, weapon, tint, bench)
if not framework.inventory?.buyTint then
return {
success = true
}
else
return framework.inventory.buyTint(src, weapon, tint)
end
end,
--[[
onApplyTint - Called when a player applies a tint to a weapon.
@param src number
@param weapon table { hashKey = string, metadata = table }
@param tint table { id = number, price = number, item = string }
@param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
@return table { success = boolean, message = string }
]]
onApplyTint = function(src, weapon, tint, bench)
if not framework.inventory?.applyTint then
return {
success = true
}
else
return framework.inventory.applyTint(src, weapon, tint)
end
end,
--[[
onRemoveTint - Called when a player removes a tint from a weapon.
@param src number
@param weapon table { hashKey = string, metadata = table }
@param tint table { id = number, price = number, item = string }
@param bench table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
@return table { success = boolean, message = string }
]]
onRemoveTint = function(src, weapon, tint, bench)
if not framework.inventory?.removeTint then
return {
success = true
}
else
return framework.inventory.removeTint(src, weapon, tint)
end
end,
--[[
getWeapons - Get the player's weapons. This is used when BenchOptions.useCurrentWeapon is set to false to show all the player's weapons.
@param src number
@return table { [number] = { data = { itemId = string, name = string }, label = string, modelHash = string } }
]]
getWeapons = function(src)
if not framework.inventory?.getWeapons then
return {}
else
return framework.inventory.getWeapons(src)
end
end,
--[[
getWeapon - Get a player's weapon.
@param src number
@param hash string
@param metadata table
@param weapon table { components = table, tints = table }
@return nil | table { components = table { [number] = { hash = string, isEquiped = boolean } }, tints = table { [number] = { id = number, isEquiped = boolean } } }
]]
getWeapon = function(src, hash, metadata, weapon)
if not framework.inventory?.getWeapon then
return {
components = {},
tints = {}
}
else
return framework.inventory?.getWeapon(src, hash, metadata, weapon)
end
end,
--[[
getWeaponMods - Get the weapon mods for a player. This is used if benchOptions.manualApplyMods is set to false in the client.lua.
@param src number
@param hash string
@param metadata table
]]
getWeaponMods = function(src, hash, metadata)
return {
components = {},
tint = nil
}
end,
--[[
doesItemExist - Check if an item exists.
@param name string
@return boolean
]]
doesItemExist = function(name)
if not framework.inventory?.doesItemExist then
return true
else
return framework.inventory.doesItemExist(name)
end
end,
database = {
init = function()
exports.oxmysql:transaction_async({
[[
CREATE TABLE IF NOT EXISTS `nxtgn_weap_benches` (
`uuid` uuid NOT NULL DEFAULT uuid(),
`title` varchar(50) NOT NULL,
`access` varchar(50) DEFAULT NULL,
`loc_x` float NOT NULL DEFAULT 0,
`loc_y` float NOT NULL DEFAULT 0,
`loc_z` float NOT NULL DEFAULT 0,
`loc_h` float NOT NULL DEFAULT 0,
`created_by` varchar(255) DEFAULT NULL,
`created_at` date NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`uuid`)
)
]]
})
end,
--[[
createBench - Create a new weapon bench.
@param data table { title = string, access = string, location = { x = number, y = number, z = number, h = number }, identifier = string }
@return string | boolean
]]
createBench = function(data)
local uuid = Math:generateUUID()
local res = exports.oxmysql:query_async([[
INSERT INTO `nxtgn_weap_benches` (`uuid`, `title`, `access`, `loc_x`, `loc_y`, `loc_z`, `loc_h`, `created_by`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
]], {
uuid,
data.title,
data.access,
data.location.x,
data.location.y,
data.location.z,
data.location.h,
data.identifier
})
if res.affectedRows == 0 then
return nil
end
return uuid
end,
--[[
updateBench - Update an existing weapon bench.
@param data table { title = string, access = string, location = { x = number, y = number, z = number, h = number }, uuid = string }
@return boolean
]]
updateBench = function(data)
local res = exports.oxmysql:query_async([[
UPDATE `nxtgn_weap_benches` SET `title` = ?, `access` = ?, `loc_x` = ?, `loc_y` = ?, `loc_z` = ?, `loc_h` = ? WHERE `uuid` = ?
]], {
data.title,
data.access,
data.location.x,
data.location.y,
data.location.z,
data.location.h,
data.uuid
})
if res.changedRows == 0 then
return false
end
return true
end,
--[[
removeBench - Remove a weapon bench.
@param data table { uuid = string }
@return boolean
]]
removeBench = function(data)
local res = exports.oxmysql:query_async([[
DELETE FROM `nxtgn_weap_benches` WHERE `uuid` = ?
]], { data.uuid })
if res.affectedRows == 0 then
return false
end
return true
end,
--[[
fetchBenches - Fetch benches.
@param data table { columnFilters = table { [string] = table { string }, orderColumn = string, orderDirection = string, count = number, offset = number }
@return nil | table { rows = table { [number] = table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }, pageCount = number }
]]
fetchBenches = function(data)
local columnFiltersTable = {}
local i = 0
for k,v in pairs(data.columnFilters) do
if i == 0 then
table.insert(columnFiltersTable, "WHERE")
elseif i > 0 then
table.insert(columnFiltersTable, "AND")
end
if type(v) == 'string' then
table.insert(columnFiltersTable, "`" .. k .. "` LIKE '" .. v .. "%'")
else
table.insert(columnFiltersTable, "`" .. k .. "` IN ('" .. table.concat(v, "','") .. "')")
end
i = i + 1
end
local columnFilters = table.concat(columnFiltersTable, ' ')
local countRow = exports.oxmysql:single_async(([[
SELECT COUNT(*) AS `count`
FROM `nxtgn_weap_benches`
%s
]]):format(columnFilters))
if not countRow or countRow.count == nil then
return nil
end
local res = exports.oxmysql:query_async(([[
SELECT
`uuid`,
`title`,
`access`,
`loc_x` AS `locationX`,
`loc_y` AS `locationY`,
`loc_z` AS `locationZ`,
`loc_h` AS `locationH`,
`created_by` AS `createdBy`,
`created_at` AS `createdAt`
FROM `nxtgn_weap_benches`
%s
ORDER BY `%s` %s
LIMIT %s OFFSET %s
]]):format(
columnFilters,
data.orderColumn,
data.orderDirection,
data.count,
data.offset
))
if not res then
return nil
end
local benches = {}
local accessIdentifiers = framework.getAccessIdentifiers()
for _, bench in ipairs(res) do
table.insert(benches, {
uuid = bench.uuid,
title = bench.title,
access = {
name = bench.access,
label = accessIdentifiers[bench.access] or bench.access,
},
location = {
x = bench.locationX,
y = bench.locationY,
z = bench.locationZ,
h = bench.locationH,
},
createdBy = bench.createdBy,
createdAt = bench.createdAt,
})
end
return {
rows = benches,
pageCount = math.ceil(countRow.count / data.count),
}
end,
--[[
fetchBench - Fetch a bench.
@param data table { uuid = string }
@return table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
]]
fetchAllBenches = function()
local benches = {}
local res = exports.oxmysql:query_async([[
SELECT
`uuid`,
`title`,
`access`,
`loc_x` AS `locationX`,
`loc_y` AS `locationY`,
`loc_z` AS `locationZ`,
`loc_h` AS `locationH`,
`created_by` AS `createdBy`,
`created_at` AS `createdAt`
FROM `nxtgn_weap_benches`
]])
if not res then
return nil
end
local accessIdentifiers = framework.getAccessIdentifiers()
for _, bench in ipairs(res) do
table.insert(benches, {
uuid = bench.uuid,
title = bench.title,
access = {
name = bench.access,
label = accessIdentifiers[bench.access] or bench.access,
},
location = {
x = bench.locationX,
y = bench.locationY,
z = bench.locationZ,
h = bench.locationH,
},
createdBy = bench.createdBy,
createdAt = bench.createdAt,
})
end
return benches
end,
--[[
fetchBench - Fetch a bench.
@param data table { uuid = string }
@return nil | table { uuid = string, title = string, access = table { name = string, label = string }, location = table { x = number, y = number, z = number, h = number }, createdBy = string, createdAt = string }
]]
fetchBench = function(data)
local res = exports.oxmysql:single_async([[
SELECT
`uuid`,
`title`,
`access`,
`loc_x` AS `locationX`,
`loc_y` AS `locationY`,
`loc_z` AS `locationZ`,
`loc_h` AS `locationH`,
`created_by` AS `createdBy`,
`created_at` AS `createdAt`
FROM `nxtgn_weap_benches` WHERE `uuid` = ?
]], {
data.uuid
})
if not res then
return nil
end
local accessIdentifiers = framework.getAccessIdentifiers()
return {
uuid = res.uuid,
title = res.title,
access = {
name = res.access,
label = accessIdentifiers[res.access] or res.access,
},
location = {
x = res.locationX,
y = res.locationY,
z = res.locationZ,
h = res.locationH,
},
createdBy = res.createdBy,
createdAt = res.createdAt,
}
end
}
}
}