Merge branch 'main' into locale

This commit is contained in:
Kakarot
2022-08-19 09:51:27 -07:00
committed by GitHub
11 changed files with 209 additions and 400 deletions
+5 -2
View File
@@ -24,9 +24,10 @@ RegisterNetEvent('QBCore:Command:TeleportToPlayer', function(coords)
SetPedCoordsKeepVehicle(ped, coords.x, coords.y, coords.z)
end)
RegisterNetEvent('QBCore:Command:TeleportToCoords', function(x, y, z)
RegisterNetEvent('QBCore:Command:TeleportToCoords', function(x, y, z, h)
local ped = PlayerPedId()
SetPedCoordsKeepVehicle(ped, x, y, z)
SetEntityHeading(ped, h or GetEntityHeading(ped))
end)
RegisterNetEvent('QBCore:Command:GoToMarker', function()
@@ -171,8 +172,10 @@ RegisterNetEvent('QBCore:Notify', function(text, type, length)
QBCore.Functions.Notify(text, type, length)
end)
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon.
RegisterNetEvent('QBCore:Client:UseItem', function(item)
TriggerServerEvent('QBCore:Server:UseItem', item)
QBCore.Debug(string.format("%s triggered QBCore:Client:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check qb-inventory for the right use on this event.", GetInvokingResource(), source))
QBCore.Debug(item)
end)
-- Callback Events --
+5 -33
View File
@@ -8,38 +8,12 @@ function QBCore.Functions.GetPlayerData(cb)
end
function QBCore.Functions.GetCoords(entity)
return vector4(GetEntityCoords(entity), GetEntityHeading(entity))
local coords = GetEntityCoords(entity)
return vector4(coords.x, coords.y, coords.z, GetEntityHeading(entity))
end
function QBCore.Functions.HasItem(items, amount)
local isTable = type(items) == 'table'
local isArray = isTable and table.type(items) == 'array' or false
local totalItems = #items
local count = 0
local kvIndex = 2
if isTable and not isArray then
totalItems = 0
for _ in pairs(items) do totalItems += 1 end
kvIndex = 1
end
for _, itemData in pairs(QBCore.PlayerData.items) do
if isTable then
for k, v in pairs(items) do
local itemKV = {k, v}
if itemData and itemData.name == itemKV[kvIndex] and ((amount and itemData.amount >= amount) or (not isArray and itemData.amount >= v) or (not amount and isArray)) then
count += 1
end
end
if count == totalItems then
return true
end
else -- Single item as string
if itemData and itemData.name == items and (not amount or (itemData and amount and itemData.amount >= amount)) then
return true
end
end
end
return false
return exports['qb-inventory']:HasItem(items, amount)
end
-- Utility
@@ -84,8 +58,8 @@ function QBCore.Functions.RequestAnimDict(animDict)
end
function QBCore.Functions.PlayAnim(animDict, animName, upperbodyOnly, duration)
local flags = upperbodyOnly == true and 16 or 0
local runTime = duration ~= nil and duration or -1
local flags = upperbodyOnly and 16 or 0
local runTime = duration or -1
QBCore.Functions.RequestAnimDict(animDict)
TaskPlayAnim(PlayerPedId(), animDict, animName, 8.0, 1.0, runTime, flags, 0.0, false, false, true)
RemoveAnimDict(animDict)
@@ -158,8 +132,6 @@ function QBCore.Functions.TriggerCallback(name, cb, ...)
TriggerServerEvent('QBCore:Server:TriggerCallback', name, ...)
end
function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
if GetResourceState('progressbar') ~= 'started' then error('progressbar needs to be started in order for QBCore.Functions.Progressbar to work') end
exports['progressbar']:Progress({
-2
View File
@@ -12,8 +12,6 @@ QBConfig.Money.PayCheckTimeOut = 10 -- The time in minutes that it will give the
QBConfig.Money.PayCheckSociety = false -- If true paycheck will come from the society account that the player is employed at, requires qb-management
QBConfig.Player = {}
QBConfig.Player.MaxWeight = 120000 -- Max weight a player can carry (currently 120kg, written in grams)
QBConfig.Player.MaxInvSlots = 41 -- Max inventory slots for a player
QBConfig.Player.HungerRate = 4.2 -- Rate at which hunger goes down.
QBConfig.Player.ThirstRate = 3.8 -- Rate at which thirst goes down.
QBConfig.Player.Bloodtypes = {
+2 -1
View File
@@ -8,6 +8,7 @@ local Translations = {
company_too_poor = 'Your employer is broke',
item_not_exist = 'Item does not exist',
too_heavy = 'Inventory too full',
location_not_exist = 'Location does not exist',
duplicate_license = 'Duplicate Rockstar License Found',
no_valid_license = 'No Valid Rockstar License Found',
not_whitelisted = 'You\'re not whitelisted for this server',
@@ -26,7 +27,7 @@ local Translations = {
off_duty = 'You are now off duty!',
checking_ban = 'Hello %s. We are checking if you are banned.',
join_server = 'Welcome %s to {Server Name}.',
checking_whitelisted = 'Hello %s. We are checking your allowance.'
checking_whitelisted = 'Hello %s. We are checking your allowance.',
}
}
+15 -19
View File
@@ -81,15 +81,23 @@ function QBCore.Commands.Refresh(source)
end
-- Teleport
QBCore.Commands.Add('tp', 'TP To Player or Coords (Admin Only)', { { name = 'id/x', help = 'ID of player or X position' }, { name = 'y', help = 'Y position' }, { name = 'z', help = 'Z position' } }, false, function(source, args)
QBCore.Commands.Add('tp', 'TP To Location/Player/Coords (Admin Only)', { { name = 'location/id/x', help = 'location name, ID of player, or X position' }, { name = 'y', help = 'Y position' }, { name = 'z', help = 'Z position' } }, false, function(source, args)
if args[1] and not args[2] and not args[3] then
local target = GetPlayerPed(tonumber(args[1]))
if target ~= 0 then
local coords = GetEntityCoords(target)
TriggerClientEvent('QBCore:Command:TeleportToPlayer', source, coords)
if tonumber(args[1]) then
local target = GetPlayerPed(tonumber(args[1]))
if target ~= 0 then
local coords = GetEntityCoords(target)
TriggerClientEvent('QBCore:Command:TeleportToPlayer', source, coords)
else
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
end
else
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
local location = QBShared.Locations[args[1]]
if location then
TriggerClientEvent('QBCore:Command:TeleportToCoords', source, location.x, location.y, location.z, location.w)
else
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.location_not_exist'), 'error')
end
end
else
if args[1] and args[2] and args[3] then
@@ -235,18 +243,6 @@ QBCore.Commands.Add('setgang', 'Set A Players Gang (Admin Only)', { { name = 'id
end
end, 'admin')
-- Inventory (should be in qb-inventory?)
QBCore.Commands.Add('clearinv', 'Clear Players Inventory (Admin Only)', { { name = 'id', help = 'Player ID' } }, false, function(source, args)
local playerId = args[1] ~= '' and args[1] or source
local Player = QBCore.Functions.GetPlayer(tonumber(playerId))
if Player then
Player.Functions.ClearInventory()
else
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
end
end, 'admin')
-- Out of Character Chat
QBCore.Commands.Add('ooc', 'OOC Chat Message', {}, false, function(source, args)
+9 -47
View File
@@ -167,24 +167,22 @@ end)
-- Items
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon.
RegisterNetEvent('QBCore:Server:UseItem', function(item)
local src = source
if not item or item.amount <= 0 or not QBCore.Functions.CanUseItem(item.name) then return end
QBCore.Functions.UseItem(src, item)
print(string.format("%s triggered QBCore:Server:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check qb-inventory for the right use on this event.", GetInvokingResource(), source))
QBCore.Debug(item)
end)
RegisterNetEvent('QBCore:Server:RemoveItem', function(itemName, amount, slot)
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon. function(itemName, amount, slot)
RegisterNetEvent('QBCore:Server:RemoveItem', function(itemName, amount)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
Player.Functions.RemoveItem(itemName, amount, slot)
print(string.format("%s triggered QBCore:Server:RemoveItem by ID %s for %s %s. This event is deprecated due to exploitation, and will be removed soon. Adjust your events accordingly to do this server side with player functions.", GetInvokingResource(), src, amount, itemName))
end)
RegisterNetEvent('QBCore:Server:AddItem', function(itemName, amount, slot, info)
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon. function(itemName, amount, slot, info)
RegisterNetEvent('QBCore:Server:AddItem', function(itemName, amount)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
Player.Functions.AddItem(itemName, amount, slot, info)
print(string.format("%s triggered QBCore:Server:AddItem by ID %s for %s %s. This event is deprecated due to exploitation, and will be removed soon. Adjust your events accordingly to do this server side with player functions.", GetInvokingResource(), src, amount, itemName))
end)
-- Non-Chat Command Calling (ex: qb-adminmenu)
@@ -206,42 +204,6 @@ RegisterNetEvent('QBCore:CallCommand', function(command, args)
end
end)
-- Has Item Callback (can also use client function - QBCore.Functions.HasItem(item))
QBCore.Functions.CreateCallback('QBCore:HasItem', function(source, cb, items, amount)
local retval = false
local Player = QBCore.Functions.GetPlayer(source)
if not Player then return cb(false) end
local isTable = type(items) == 'table'
local isArray = isTable and table.type(items) == 'array' or false
local totalItems = #items
local count = 0
local kvIndex = 2
if isTable and not isArray then
totalItems = 0
for _ in pairs(items) do totalItems += 1 end
kvIndex = 1
end
if isTable then
for k, v in pairs(items) do
local itemKV = {k, v}
local item = Player.Functions.GetItemByName(itemKV[kvIndex])
if item and ((amount and item.amount >= amount) or (not amount and not isArray and item.amount >= v) or (not amount and isArray)) then
count += 1
end
end
if count == totalItems then
retval = true
end
else -- Single item as string
local item = Player.Functions.GetItemByName(items)
if item and not amount or (item and amount and item.amount >= amount) then
retval = true
end
end
cb(retval)
end)
-- Use this for player vehicle spawning
-- Vehicle server-side spawning callback (netId)
-- use the netid on the client with the NetworkGetEntityFromNetworkId native
+32
View File
@@ -1,3 +1,35 @@
-- Add or change (a) method(s) in the QBCore.Functions table
local function SetMethod(methodName, handler)
if type(methodName) ~= "string" then
return false, "invalid_method_name"
end
QBCore.Functions[methodName] = handler
TriggerEvent('QBCore:Server:UpdateObject')
return true, "success"
end
QBCore.Functions.SetMethod = SetMethod
exports("SetMethod", SetMethod)
-- Add or change (a) field(s) in the QBCore table
local function SetField(fieldName, data)
if type(fieldName) ~= "string" then
return false, "invalid_field_name"
end
QBCore[fieldName] = data
TriggerEvent('QBCore:Server:UpdateObject')
return true, "success"
end
QBCore.Functions.SetField = SetField
exports("SetField", SetField)
-- Single add job function which should only be used if you planning on adding a single job
local function AddJob(jobName, job)
if type(jobName) ~= "string" then
+18 -34
View File
@@ -199,7 +199,6 @@ function QBCore.Functions.CreateVehicle(source, model, coords, warp)
end
-- Paychecks (standalone - don't touch)
function PaycheckInterval()
if next(QBCore.Players) then
for _, Player in pairs(QBCore.Players) do
@@ -253,15 +252,28 @@ end
-- Items
function QBCore.Functions.CreateUseableItem(item, cb)
QBCore.UseableItems[item] = cb
if GetResourceState('qb-inventory') == 'missing' then return end
if GetResourceState('qb-inventory') ~= 'started' then
CreateThread(function()
repeat
Wait(1000)
until GetResourceState('qb-inventory') == 'started'
exports['qb-inventory']:CreateUsableItem(item, cb)
end)
else
exports['qb-inventory']:CreateUsableItem(item, cb)
end
end
function QBCore.Functions.CanUseItem(item)
return QBCore.UseableItems[item]
if GetResourceState('qb-inventory') == 'missing' then return end
return exports['qb-inventory']:GetUsableItem(item)
end
function QBCore.Functions.UseItem(source, item)
QBCore.UseableItems[item.name](source, item)
if GetResourceState('qb-inventory') == 'missing' then return end
exports['qb-inventory']:UseItem(source, item)
end
-- Kick Player
@@ -402,36 +414,8 @@ end
-- Utility functions
function QBCore.Functions.HasItem(source, items, amount)
local Player = QBCore.Functions.GetPlayer(source)
if not Player then return false end
local isTable = type(items) == 'table'
local isArray = isTable and table.type(items) == 'array' or false
local totalItems = #items
local count = 0
local kvIndex = 2
if isTable and not isArray then
totalItems = 0
for _ in pairs(items) do totalItems += 1 end
kvIndex = 1
end
if isTable then
for k, v in pairs(items) do
local itemKV = {k, v}
local item = Player.Functions.GetItemByName(itemKV[kvIndex])
if item and ((amount and item.amount >= amount) or (not isArray and item.amount >= v) or (not amount and isArray)) then
count += 1
end
end
if count == totalItems then
return true
end
else -- Single item as string
local item = Player.Functions.GetItemByName(items)
if item and (not amount or (item and amount and item.amount >= amount)) then
return true
end
end
return false
if GetResourceState('qb-inventory') == 'missing' then return end
return exports['qb-inventory']:HasItem(source, items, amount)
end
function QBCore.Functions.Notify(source, text, type, length)
+65 -261
View File
@@ -60,7 +60,7 @@ end
function QBCore.Player.CheckPlayerData(source, PlayerData)
PlayerData = PlayerData or {}
local Offline = true
if source ~= nil then
if source then
PlayerData.source = source
PlayerData.license = PlayerData.license or QBCore.Functions.GetIdentifier(source, 'license')
PlayerData.name = GetPlayerName(source)
@@ -74,6 +74,7 @@ function QBCore.Player.CheckPlayerData(source, PlayerData)
for moneytype, startamount in pairs(QBCore.Config.Money.MoneyTypes) do
PlayerData.money[moneytype] = PlayerData.money[moneytype] or startamount
end
-- Charinfo
PlayerData.charinfo = PlayerData.charinfo or {}
PlayerData.charinfo.firstname = PlayerData.charinfo.firstname or 'Firstname'
@@ -158,7 +159,7 @@ function QBCore.Player.CheckPlayerData(source, PlayerData)
PlayerData.gang.grade.level = PlayerData.gang.grade.level or 0
-- Other
PlayerData.position = PlayerData.position or QBConfig.DefaultSpawn
PlayerData = QBCore.Player.LoadInventory(PlayerData)
PlayerData.items = GetResourceState('qb-inventory') ~= 'missing' and exports['qb-inventory']:LoadInventory(PlayerData.source, PlayerData.citizenid) or {}
return QBCore.Player.CreatePlayer(PlayerData, Offline)
end
@@ -166,6 +167,7 @@ end
function QBCore.Player.Logout(source)
TriggerClientEvent('QBCore:Client:OnPlayerUnload', source)
TriggerEvent('QBCore:Server:OnPlayerUnload', source)
TriggerClientEvent('QBCore:Player:UpdatePlayerData', source)
Wait(200)
QBCore.Players[source] = nil
@@ -183,6 +185,7 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
function self.Functions.UpdatePlayerData(dontUpdateChat)
if self.Offline then return end -- Unsupported for Offline Players
TriggerEvent('QBCore:Player:SetPlayerData', self.PlayerData)
TriggerClientEvent('QBCore:Player:SetPlayerData', self.PlayerData.source, self.PlayerData)
if not dontUpdateChat then
QBCore.Commands.Refresh(self.PlayerData.source)
@@ -242,6 +245,7 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('QBCore:Server:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
TriggerClientEvent('QBCore:Client:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
end
@@ -266,6 +270,12 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
self.Functions.UpdatePlayerData()
end
function self.Functions.GetMetaData(meta)
if not meta or type(meta) ~= 'string' then return end
meta = meta:lower()
return self.PlayerData.metadata[meta]
end
function self.Functions.AddJobReputation(amount)
if not amount then return end
amount = tonumber(amount)
@@ -347,148 +357,6 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
return self.PlayerData.money[moneytype]
end
function self.Functions.AddItem(item, amount, slot, info)
local totalWeight = QBCore.Player.GetTotalWeight(self.PlayerData.items)
local itemInfo = QBCore.Shared.Items[item:lower()]
if not itemInfo and not self.Offline then
TriggerClientEvent('QBCore:Notify', self.PlayerData.source, Lang:t('error.item_not_exist'), 'error')
return
end
amount = tonumber(amount)
slot = tonumber(slot) or QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item)
if itemInfo['type'] == 'weapon' and not info then
info = {
serie = tostring(QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(1) .. QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(4)),
}
end
if (totalWeight + (itemInfo['weight'] * amount)) <= QBCore.Config.Player.MaxWeight then
if (slot and self.PlayerData.items[slot]) and (self.PlayerData.items[slot].name:lower() == item:lower()) and (itemInfo['type'] == 'item' and not itemInfo['unique']) then
self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount + amount
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount)
end
return true
elseif not itemInfo['unique'] and slot or slot and self.PlayerData.items[slot] == nil then
self.PlayerData.items[slot] = { name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = slot, combinable = itemInfo['combinable'] }
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount)
end
return true
elseif itemInfo['unique'] or (not slot or slot == nil) or itemInfo['type'] == 'weapon' then
for i = 1, QBConfig.Player.MaxInvSlots, 1 do
if self.PlayerData.items[i] == nil then
self.PlayerData.items[i] = { name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = i, combinable = itemInfo['combinable'] }
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. i .. '], itemname: ' .. self.PlayerData.items[i].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[i].amount)
end
return true
end
end
end
elseif not self.Offline then
TriggerClientEvent('QBCore:Notify', self.PlayerData.source, Lang:t('error.too_heavy'), 'error')
end
return false
end
function self.Functions.RemoveItem(item, amount, slot)
amount = tonumber(amount)
slot = tonumber(slot)
if slot then
if self.PlayerData.items[slot].amount > amount then
self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount - amount
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', removed amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount)
end
return true
elseif self.PlayerData.items[slot].amount == amount then
self.PlayerData.items[slot] = nil
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. item .. ', removed amount: ' .. amount .. ', item removed')
end
return true
end
else
local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item)
local amountToRemove = amount
if slots then
for _, _slot in pairs(slots) do
if self.PlayerData.items[_slot].amount > amountToRemove then
self.PlayerData.items[_slot].amount = self.PlayerData.items[_slot].amount - amountToRemove
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. _slot .. '], itemname: ' .. self.PlayerData.items[_slot].name .. ', removed amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[_slot].amount)
end
return true
elseif self.PlayerData.items[_slot].amount == amountToRemove then
self.PlayerData.items[_slot] = nil
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. _slot .. '], itemname: ' .. item .. ', removed amount: ' .. amount .. ', item removed')
end
return true
end
end
end
end
return false
end
function self.Functions.SetInventory(items, dontUpdateChat)
self.PlayerData.items = items
if not self.Offline then
self.Functions.UpdatePlayerData(dontUpdateChat)
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'SetInventory', 'blue', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** items set: ' .. json.encode(items))
end
end
function self.Functions.ClearInventory()
self.PlayerData.items = {}
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'ClearInventory', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** inventory cleared')
end
end
function self.Functions.GetItemByName(item)
item = tostring(item):lower()
local slot = QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item)
return self.PlayerData.items[slot]
end
function self.Functions.GetItemsByName(item)
item = tostring(item):lower()
local items = {}
local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item)
for _, slot in pairs(slots) do
if slot then
items[#items+1] = self.PlayerData.items[slot]
end
end
return items
end
function self.Functions.SetCreditCard(cardNumber)
self.PlayerData.charinfo.card = cardNumber
self.Functions.UpdatePlayerData()
@@ -496,7 +364,7 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
function self.Functions.GetCardSlot(cardNumber, cardType)
local item = tostring(cardType):lower()
local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item)
local slots = exports['qb-inventory']:GetSlotsByItem(self.PlayerData.items, item)
for _, slot in pairs(slots) do
if slot then
if self.PlayerData.items[slot].info.cardNumber == cardNumber then
@@ -507,15 +375,6 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
return nil
end
function self.Functions.GetItemBySlot(slot)
slot = tonumber(slot)
return self.PlayerData.items[slot]
end
function self.Functions.AddMethod(methodName, handler)
self.Functions[methodName] = handler
end
function self.Functions.Save()
if self.Offline then
QBCore.Player.SaveOffline(self.PlayerData)
@@ -529,6 +388,14 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
QBCore.Player.Logout(self.PlayerData.source)
end
function self.Functions.AddMethod(methodName, handler)
self.Functions[methodName] = handler
end
function self.Functions.AddField(fieldName, data)
self[fieldName] = data
end
if self.Offline then
return self
else
@@ -544,8 +411,8 @@ end
-- Add a new function to the Functions table of the player class
-- Use-case:
--[[
AddEventHandler('QBCore:Server:PlayerLoaded', function(player)
QBCore.Functions.AddPlayerMethod(player.PlayerData.source, "functionName", function(oneArg, orMore)
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
QBCore.Functions.AddPlayerMethod(Player.PlayerData.source, "functionName", function(oneArg, orMore)
-- do something here
end)
end)
@@ -570,6 +437,33 @@ function QBCore.Functions.AddPlayerMethod(ids, methodName, handler)
end
end
-- Add a new field table of the player class
-- Use-case:
--[[
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
QBCore.Functions.AddPlayerField(Player.PlayerData.source, "fieldName", "fieldData")
end)
]]
function QBCore.Functions.AddPlayerField(ids, fieldName, data)
local idType = type(ids)
if idType == "number" then
if ids == -1 then
for _, v in pairs(QBCore.Players) do
v.Functions.AddField(fieldName, data)
end
else
if not QBCore.Players[ids] then return end
QBCore.Players[ids].Functions.AddField(fieldName, data)
end
elseif idType == "table" and table.type(ids) == "array" then
for i = 1, #ids do
QBCore.Functions.AddPlayerField(ids[i], fieldName, data)
end
end
end
-- Save player info to database (make sure citizenid is the primary key in your database)
function QBCore.Player.Save(source)
@@ -589,7 +483,7 @@ function QBCore.Player.Save(source)
position = json.encode(pcoords),
metadata = json.encode(PlayerData.metadata)
})
QBCore.Player.SaveInventory(source)
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(source) end
QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name .. ' PLAYER SAVED!')
else
QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
@@ -610,7 +504,7 @@ function QBCore.Player.SaveOffline(PlayerData)
position = json.encode(PlayerData.position),
metadata = json.encode(PlayerData.metadata)
})
QBCore.Player.SaveOfflineInventory(PlayerData)
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(PlayerData, true) end
QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name .. ' OFFLINE PLAYER SAVED!')
else
QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVEOFFLINE - PLAYERDATA IS EMPTY!')
@@ -658,125 +552,35 @@ function QBCore.Player.DeleteCharacter(source, citizenid)
end
end
-- Inventory
function QBCore.Player.LoadInventory(PlayerData)
PlayerData.items = {}
local inventory = MySQL.prepare.await('SELECT inventory FROM players WHERE citizenid = ?', { PlayerData.citizenid })
local missingItems = {}
if inventory then
inventory = json.decode(inventory)
if next(inventory) then
for _, item in pairs(inventory) do
if item then
local itemInfo = QBCore.Shared.Items[item.name:lower()]
if itemInfo then
PlayerData.items[item.slot] = {
name = itemInfo['name'],
amount = item.amount,
info = item.info or '',
label = itemInfo['label'],
description = itemInfo['description'] or '',
weight = itemInfo['weight'],
type = itemInfo['type'],
unique = itemInfo['unique'],
useable = itemInfo['useable'],
image = itemInfo['image'],
shouldClose = itemInfo['shouldClose'],
slot = item.slot,
combinable = itemInfo['combinable']
}
else
missingItems[#missingItems+1] = item.name:lower()
end
end
end
end
end
if #missingItems > 0 then
print(("%s the following items removed as they no longer exist: %s"):format(GetPlayerName(PlayerData.source), json.encode(missingItems)))
end
return PlayerData
end
-- Inventory Backwards Compatibility
function QBCore.Player.SaveInventory(source)
if not QBCore.Players[source] then return end
local PlayerData = QBCore.Players[source].PlayerData
local items = PlayerData.items
local ItemsJson = {}
if items and next(items) then
for slot, item in pairs(items) do
if items[slot] then
ItemsJson[#ItemsJson+1] = {
name = item.name,
amount = item.amount,
info = item.info,
type = item.type,
slot = slot,
}
end
end
MySQL.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid })
else
MySQL.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid })
end
if GetResourceState('qb-inventory') == 'missing' then return end
exports['qb-inventory']:SaveInventory(source, false)
end
function QBCore.Player.SaveOfflineInventory(PlayerData)
local items = PlayerData.items
local ItemsJson = {}
if items and next(items) then
for slot, item in pairs(items) do
if items[slot] then
ItemsJson[#ItemsJson+1] = {
name = item.name,
amount = item.amount,
info = item.info,
type = item.type,
slot = slot,
}
end
end
MySQL.Async.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid })
else
MySQL.Async.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid })
end
if GetResourceState('qb-inventory') == 'missing' then return end
exports['qb-inventory']:SaveInventory(PlayerData, true)
end
-- Util Functions
function QBCore.Player.GetTotalWeight(items)
local weight = 0
if not items then return 0 end
for _, item in pairs(items) do
weight += item.weight * item.amount
end
return tonumber(weight)
if GetResourceState('qb-inventory') == 'missing' then return end
return exports['qb-inventory']:GetTotalWeight(items)
end
function QBCore.Player.GetSlotsByItem(items, itemName)
local slotsFound = {}
if not items then return slotsFound end
for slot, item in pairs(items) do
if item.name:lower() == itemName:lower() then
slotsFound[#slotsFound+1] = slot
end
end
return slotsFound
if GetResourceState('qb-inventory') == 'missing' then return end
return exports['qb-inventory']:GetSlotsByItem(items, itemName)
end
function QBCore.Player.GetFirstSlotByItem(items, itemName)
if not items then return nil end
for slot, item in pairs(items) do
if item.name:lower() == itemName:lower() then
return tonumber(slot)
end
end
return nil
if GetResourceState('qb-inventory') == 'missing' then return end
return exports['qb-inventory']:GetFirstSlotByItem(items, itemName)
end
-- Util Functions
function QBCore.Player.CreateCitizenId()
local UniqueFound = false
local CitizenId = nil
-1
View File
@@ -386,7 +386,6 @@ QBShared.Items = {
['moneybag'] = {['name'] = 'moneybag', ['label'] = 'Money Bag', ['weight'] = 0, ['type'] = 'item', ['image'] = 'moneybag.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A bag with cash'},
['parachute'] = {['name'] = 'parachute', ['label'] = 'Parachute', ['weight'] = 30000, ['type'] = 'item', ['image'] = 'parachute.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'The sky is the limit! Woohoo!'},
['binoculars'] = {['name'] = 'binoculars', ['label'] = 'Binoculars', ['weight'] = 600, ['type'] = 'item', ['image'] = 'binoculars.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Sneaky Breaky...'},
['snowball'] = {['name'] = 'snowball', ['label'] = 'Snowball', ['weight'] = 0, ['type'] = 'item', ['image'] = 'snowball.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Should have catched it :D'},
['lighter'] = {['name'] = 'lighter', ['label'] = 'Lighter', ['weight'] = 0, ['type'] = 'item', ['image'] = 'lighter.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'On new years eve a nice fire to stand next to'},
['certificate'] = {['name'] = 'certificate', ['label'] = 'Certificate', ['weight'] = 0, ['type'] = 'item', ['image'] = 'certificate.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Certificate that proves you own certain stuff'},
['markedbills'] = {['name'] = 'markedbills', ['label'] = 'Marked Money', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'markedbills.png', ['unique'] = true, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Money?'},
+58
View File
@@ -0,0 +1,58 @@
QBShared.Locations = {
-- Unknown/Random/Vanilla
['burgershot'] = vector4(-1199.0568, -882.4495, 13.3500, 209.1105),
['casino'] = vector4(923.2289, 47.3113, 81.1063, 237.6052),
-- Gabz
['arcade'] = vector4(-1649.6089, -1083.9313, 13.1575, 46.4121),
['beanmachinelegion'] = vector4(116.16, -1022.99, 29.3, 0.0),
['bowling'] = vector4(761.5008, -777.7256, 26.3078, 90.5581),
['pizzaria'] = vector4(790.4561, -758.4601, 26.7424, 270.2329),
['catcafe'] = vector4(-580.8388, -1072.7872, 22.3296, 359.0078),
['carmeet'] = vector4(958.8237, -1699.6659, 29.5574, 71.2731),
['davispd'] = vector4(382.5791, -1591.1827, 29.2828, 145.0991),
['popsdiner'] = vector4(1595.9753, 6448.6421, 25.3170, 28.3026),
['davisfirestation'] = vector4(216.7576, -1638.3801, 29.5151, 137.8174),
['harmony'] = vector4(1183.0693, 2648.5313, 37.8363, 194.0603),
['haters'] = vector4(-1117.1525, -1439.4297, 5.1075, 103.4411),
['hayes'] = vector4(-1435.7040, -445.7360, 35.5964, 220.1762),
['pdm'] = vector4(-48.2113, -1105.4769, 27.2634, 339.5899),
['bennys'] = vector4(-47.5289, -1042.6086, 28.3532, 247.9748),
['impound'] = vector4(-190.5874, -1156.1343, 23.0482, 158.9385),
['lamesaauto'] = vector4(720.4776, -1092.1934, 22.2866, 310.1469),
['lamesapd'] = vector4(824.3735, -1290.0670, 28.2364, 266.1293),
['lostmc'] = vector4(982.6339, -104.7095, 74.8488, 30.8738),
['pillbox'] = vector4(298.1153, -584.2825, 43.2609, 252.7553),
['mrpd'] = vector4(432.0686, -981.6853, 30.7119, 267.3501),
['mirrorparkhouse1'] = vector4(945.9535, -652.9119, 58.0228, 90.5541),
['pacificbank'] = vector4(229.9529, 214.3890, 105.5561, 294.6791),
['paletoliquor'] = vector4(-154.2287, 6328.8682, 31.5665, 133.1992),
['paletopd'] = vector4(-436.0935, 6015.2026, 31.4892, 132.9752),
['paletogasstation'] = vector4(120.2420, 6625.4722, 31.9580, 36.5687),
['pinkcage'] = vector4(323.9055, -203.2524, 54.0866, 186.8505),
['ponsonbys1'] = vector4(-165.2497, -304.3988, 38.07126, 0.0),
['ponsonbys2'] = vector4(-1448.1, -236.8420, 48.15098, 0.0),
['ponsonbys3'] = vector4(-709.8120, -150.6267, 35.75312, 0.0),
['prison'] = vector4(1847.1284, 2586.0696, 45.6726, 91.7828),
['rangerstation'] = vector4(387.3204, 790.1508, 187.6927, 4.7656),
['recordastudio'] = vector4(473.3006, -109.4360, 62.7418, 350.8488),
['sandypd'] = vector4(1839.7510, 3667.9907, 33.8787, 29.1744),
['suburban1'] = vector4(124.9756, -217.6290, 55.81879, 0.0),
['suburban2'] = vector4(617.4776, 2757.4810, 43.34935, 0.0),
['suburban3'] = vector4(-1195.8690, -773.5746, 18.58485, 0.0),
['suburban4'] = vector4(-3170.9670, 1049.9310, 22.12445, 0.0),
['triadrecords'] = vector4(-829.0061, -698.2049, 28.0583, 291.2052),
['tuner'] = vector4(157.5888, -3017.9968, 7.0400, 94.0695),
['vu'] = vector4(129.4555, -1299.6754, 29.2327, 27.6378),
-- Patoche
['luxerydealership'] = vector4(-1273.22, -371.11, 36.64, 301.8),
-- Unclejust
['digitalden'] = vector4(-656.28, -849.92, 24.51, 167.42),
['ifruitstore1'] = vector4(-646.78, -288.17, 35.49, 297.73),
['ifruitstore2'] = vector4(-778.7451, -598.2717, 30.2772, 181.0197),
['taxijob'] = vector4(908.7, -166.45, 74.13, 54.88),
['vineyard'] = vector4(-1892.29, 2038.47, 140.86, 339.23),
['weazelnews'] = vector4(-604.82, -933.22, 23.86, 292.3),
}