From ef6b66ab3ea9dcdbfc7f88d607cb75750f43b81f Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 22 May 2022 18:32:43 +0100 Subject: [PATCH] refactor - es_extended - PlayerOverride Functionality --- [esx]/es_extended/client/main.lua | 2 + .../server/classes/overrides/oxinventory.lua | 216 ++++ [esx]/es_extended/server/classes/player.lua | 132 +-- [esx]/es_extended/server/commands.lua | 2 + [esx]/es_extended/server/common.lua | 2 + [esx]/es_extended/server/functions.lua | 19 +- [esx]/es_extended/server/main.lua | 1035 +++++++++-------- 7 files changed, 796 insertions(+), 612 deletions(-) create mode 100644 [esx]/es_extended/server/classes/overrides/oxinventory.lua diff --git a/[esx]/es_extended/client/main.lua b/[esx]/es_extended/client/main.lua index 2861d4ef..f20c60a3 100644 --- a/[esx]/es_extended/client/main.lua +++ b/[esx]/es_extended/client/main.lua @@ -75,6 +75,8 @@ AddEventHandler('esx:playerLoaded', function(xPlayer, isNew, skin) grade_label = gradeLabel }) end + + FreezeEntityPosition(PlayerPedId(), false) StartServerSyncLoops() end) diff --git a/[esx]/es_extended/server/classes/overrides/oxinventory.lua b/[esx]/es_extended/server/classes/overrides/oxinventory.lua new file mode 100644 index 00000000..dcc5ceb8 --- /dev/null +++ b/[esx]/es_extended/server/classes/overrides/oxinventory.lua @@ -0,0 +1,216 @@ +local Inventory + +if Config.OxInventory then + AddEventHandler('ox_inventory:loadInventory', function(module) + Inventory = module + end) +end + +Core.PlayerFunctionOverrides.OxInventory = { + getInventory = function(self) + return function() + local res = {} + + for k, v in pairs(self.inventory) do + if v.count and v.count > 0 then + local metadata = v.metadata + + if v.metadata and next(v.metadata) == nil then + metadata = nil + end + + res[#res+1] = { + name = v.name, + count = v.count, + slot = k, + metadata = metadata + } + end + end + + return res + end + end, + + getLoadout = function(self) + return function() + return {} + end + end, + + setAccountMoney = function(self) + return function(accountName,money) + if money >= 0 then + local account = self.getAccount(accountName) + + if account then + local newMoney = ESX.Math.Round(money) + account.money = newMoney + + self.triggerEvent('esx:setAccountMoney', account) + + if Inventory.accounts[accountName] then + Inventory.SetItem(self.source, accountName, money) + end + end + end + end + end, + + addAccountMoney = function(self) + return function(accountName,money) + if money > 0 then + local account = self.getAccount(accountName) + + if account then + local newMoney = account.money + ESX.Math.Round(money) + account.money = newMoney + + self.triggerEvent('esx:setAccountMoney', account) + + if Inventory.accounts[accountName] then + Inventory.AddItem(self.source, accountName, money) + end + end + end + end + end, + + removeAccountMoney = function(self) + return function(accountName,money) + if money > 0 then + local account = self.getAccount(accountName) + + if account then + local newMoney = account.money - ESX.Math.Round(money) + account.money = newMoney + + self.triggerEvent('esx:setAccountMoney', account) + + if Inventory.accounts[accountName] then + Inventory.RemoveItem(self.source, accountName, money) + end + end + end + end + end, + + getInventoryItem = function(self) + return function(name,metadata) + return Inventory.GetItem(self.source, name, metadata) + end + end, + + addInventoryItem = function(self) + return function(name,count,metadata,slot) + return Inventory.AddItem(self.source, name, count or 1, metadata, slot) + end + end, + + removeInventoryItem = function(self) + return function(name,count,metadata,slot) + return Inventory.RemoveItem(self.source, name, count or 1, metadata, slot) + end + end, + + setInventoryItem = function(self) + return function(name,count,metadata) + return Inventory.SetItem(self.source, name, count, metadata) + end + end, + + canCarryItem = function(self) + return function(name,count,metadata) + return Inventory.CanCarryItem(self.source, name, count, metadata) + end + end, + + canSwapItem = function(self) + return function(firstItem, firstItemCount, testItem, testItemCount) + return Inventory.CanSwapItem(self.source, firstItem, firstItemCount, testItem, testItemCount) + end + end, + + setMaxWeight = function(self) + return function(newWeight) + self.maxWeight = newWeight + self.triggerEvent('esx:setMaxWeight', self.maxWeight) + return Inventory.Set(self.source, 'maxWeight', newWeight) + end + end, + + addWeapon = function(self) + return function() end + end, + + addWeaponComponent = function(self) + return function() end + end, + + addWeaponAmmo = function(self) + return function() end + end, + + updateWeaponAmmo = function(self) + return function() end + end, + + setWeaponTint = function(self) + return function() end + end, + + getWeaponTint = function(self) + return function() end + end, + + removeWeapon = function(self) + return function() end + end, + + removeWeaponComponent = function(self) + return function() end + end, + + removeWeaponAmmo = function(self) + return function() end + end, + + hasWeaponComponent = function(self) + return function() + return false + end + end, + + hasWeapon = function(self) + return function() + return false + end + end, + + hasItem = function(self) + return function(name,metadata) + return Inventory.GetItem(self.source, name, metadata) + end + end, + + getWeapon = function(self) + return function() end + end, + + syncInventory = function(self) + return function(weight, maxWeight, items, money) + self.weight, self.maxWeight = weight, maxWeight + self.inventory = items + + if money then + for k, v in pairs(money) do + local account = self.getAccount(k) + if ESX.Math.Round(account.money) ~= v then + account.money = v + self.triggerEvent('esx:setAccountMoney', account) + end + end + end + end + end +} \ No newline at end of file diff --git a/[esx]/es_extended/server/classes/player.lua b/[esx]/es_extended/server/classes/player.lua index 9b99915a..7d0e91fd 100644 --- a/[esx]/es_extended/server/classes/player.lua +++ b/[esx]/es_extended/server/classes/player.lua @@ -1,12 +1,6 @@ -local Inventory - -if Config.OxInventory then - AddEventHandler('ox_inventory:loadInventory', function(module) - Inventory = module - end) -end - function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, loadout, name, coords) + local targetOverrides = Config.PlayerFunctionOverride and Core.PlayerFunctionOverrides[Config.PlayerFunctionOverride] or {} + local self = {} self.accounts = accounts @@ -118,28 +112,9 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if minimal then local minimalInventory = {} - if not Inventory then - for k, v in ipairs(self.inventory) do - if v.count > 0 then - minimalInventory[v.name] = v.count - end - end - else - for k, v in pairs(self.inventory) do - if v.count and v.count > 0 then - local metadata = v.metadata - - if v.metadata and next(v.metadata) == nil then - metadata = nil - end - - minimalInventory[#minimalInventory+1] = { - name = v.name, - count = v.count, - slot = k, - metadata = metadata - } - end + for k, v in ipairs(self.inventory) do + if v.count > 0 then + minimalInventory[v.name] = v.count end end @@ -154,7 +129,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.getLoadout(minimal) - if Inventory then return {} end if minimal then local minimalLoadout = {} @@ -200,10 +174,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, account.money = newMoney self.triggerEvent('esx:setAccountMoney', account) - - if Inventory and Inventory.accounts[accountName] then - Inventory.SetItem(self.source, accountName, money) - end end end end @@ -217,10 +187,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, account.money = newMoney self.triggerEvent('esx:setAccountMoney', account) - - if Inventory and Inventory.accounts[accountName] then - Inventory.AddItem(self.source, accountName, money) - end end end end @@ -234,19 +200,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, account.money = newMoney self.triggerEvent('esx:setAccountMoney', account) - - if Inventory and Inventory.accounts[accountName] then - Inventory.RemoveItem(self.source, accountName, money) - end end end end function self.getInventoryItem(name, metadata) - if Inventory then - return Inventory.GetItem(self.source, name, metadata) - end - for k,v in ipairs(self.inventory) do if v.name == name then return v @@ -255,10 +213,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.addInventoryItem(name, count, metadata, slot) - if Inventory then - return Inventory.AddItem(self.source, name, count or 1, metadata, slot) - end - local item = self.getInventoryItem(name) if item then @@ -272,10 +226,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.removeInventoryItem(name, count, metadata, slot) - if Inventory then - return Inventory.RemoveItem(self.source, name, count or 1, metadata, slot) - end - local item = self.getInventoryItem(name) if item then @@ -293,10 +243,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.setInventoryItem(name, count, metadata) - if Inventory then - return Inventory.SetItem(self.source, name, count, metadata) - end - local item = self.getInventoryItem(name) if item and count >= 0 then @@ -319,10 +265,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.canCarryItem(name, count, metadata) - if Inventory then - return Inventory.CanCarryItem(self.source, name, count, metadata) - end - local currentWeight, itemWeight = self.weight, ESX.Items[name].weight local newWeight = currentWeight + (itemWeight * count) @@ -330,10 +272,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.canSwapItem(firstItem, firstItemCount, testItem, testItemCount) - if Inventory then - return Inventory.CanSwapItem(self.source, firstItem, firstItemCount, testItem, testItemCount) - end - local firstItemObject = self.getInventoryItem(firstItem) local testItemObject = self.getInventoryItem(testItem) @@ -350,17 +288,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, function self.setMaxWeight(newWeight) self.maxWeight = newWeight self.triggerEvent('esx:setMaxWeight', self.maxWeight) - - if Inventory then - return Inventory.Set(self.source, 'maxWeight', newWeight) - end end - function self.setDuty(bool) - self.job.onDuty = bool - self.triggerEvent('esx:setJob', self.job) - end - function self.setJob(job, grade) grade = tostring(grade) local lastJob = json.decode(json.encode(self.job)) @@ -376,7 +305,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.job.grade_name = gradeObject.name self.job.grade_label = gradeObject.label self.job.grade_salary = gradeObject.salary - self.job.onDuty = Config.OnDuty if gradeObject.skin_male then self.job.skin_male = json.decode(gradeObject.skin_male) @@ -398,8 +326,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.addWeapon(weaponName, ammo) - if Inventory then return end - if not self.hasWeapon(weaponName) then local weaponLabel = ESX.GetWeaponLabel(weaponName) @@ -417,8 +343,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.addWeaponComponent(weaponName, weaponComponent) - if Inventory then return end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then @@ -435,8 +359,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.addWeaponAmmo(weaponName, ammoCount) - if Inventory then return end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then @@ -446,18 +368,16 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.updateWeaponAmmo(weaponName, ammoCount) - if Inventory then return end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then - weapon.ammo = ammoCount + if ammoCount < weapon.ammo then + weapon.ammo = ammoCount + end end end function self.setWeaponTint(weaponName, weaponTintIndex) - if Inventory then return end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then @@ -472,8 +392,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.getWeaponTint(weaponName) - if Inventory then return 0 end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then @@ -484,8 +402,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.removeWeapon(weaponName) - if Inventory then return end - local weaponLabel for k,v in ipairs(self.loadout) do @@ -508,8 +424,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.removeWeaponComponent(weaponName, weaponComponent) - if Inventory then return end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then @@ -532,8 +446,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.removeWeaponAmmo(weaponName, ammoCount) - if Inventory then return end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then @@ -543,8 +455,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.hasWeaponComponent(weaponName, weaponComponent) - if Inventory then return false end - local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then @@ -561,8 +471,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.hasWeapon(weaponName) - if Inventory then return false end - for k,v in ipairs(self.loadout) do if v.name == weaponName then return true @@ -573,10 +481,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end function self.hasItem(item, metadata) - if Inventory then - return Inventory.GetItem(self.source, item, metadata) - end - for k,v in ipairs(self.inventory) do if (v.name == item) and (v.count >= 1) then return v, v.count @@ -586,10 +490,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return false end - function self.getWeapon(weaponName) - if Inventory then return end - for k,v in ipairs(self.loadout) do if v.name == weaponName then return k, v @@ -605,21 +506,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.triggerEvent('esx:showHelpNotification', msg, thisFrame, beep, duration) end - if Inventory then - self.syncInventory = function(weight, maxWeight, items, money) - self.weight, self.maxWeight = weight, maxWeight - self.inventory = items - - if money then - for k, v in pairs(money) do - local account = self.getAccount(k) - if ESX.Math.Round(account.money) ~= v then - account.money = v - self.triggerEvent('esx:setAccountMoney', account) - end - end - end - end + for fnName,fn in pairs(targetOverrides) do + self[fnName] = fn(self) end return self diff --git a/[esx]/es_extended/server/commands.lua b/[esx]/es_extended/server/commands.lua index a6122c73..50cfccb7 100644 --- a/[esx]/es_extended/server/commands.lua +++ b/[esx]/es_extended/server/commands.lua @@ -115,6 +115,7 @@ if not Config.OxInventory then args.playerId.setInventoryItem(v.name, 0) end end + TriggerEvent('esx:playerInventoryCleared',args.playerId) end, true, {help = _U('command_clearinventory'), validate = true, arguments = { {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} }}) @@ -123,6 +124,7 @@ if not Config.OxInventory then for i=#args.playerId.loadout, 1, -1 do args.playerId.removeWeapon(args.playerId.loadout[i].name) end + TriggerEvent('esx:playerLoadoutCleared',args.playerId) end, true, {help = _U('command_clearloadout'), validate = true, arguments = { {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} }}) diff --git a/[esx]/es_extended/server/common.lua b/[esx]/es_extended/server/common.lua index 29a702bc..468ead43 100644 --- a/[esx]/es_extended/server/common.lua +++ b/[esx]/es_extended/server/common.lua @@ -10,6 +10,7 @@ Core.CancelledTimeouts = {} Core.RegisteredCommands = {} Core.Pickups = {} Core.PickupId = 0 +Core.PlayerFunctionOverrides = {} AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) @@ -21,6 +22,7 @@ end) if GetResourceState('ox_inventory') ~= 'missing' then Config.OxInventory = true + Config.PlayerFunctionOverride = 'OxInventory' SetConvarReplicated('inventory:framework', 'esx') SetConvarReplicated('inventory:weight', Config.MaxWeight * 1000) end diff --git a/[esx]/es_extended/server/functions.lua b/[esx]/es_extended/server/functions.lua index 79e89b0c..cf346c8d 100644 --- a/[esx]/es_extended/server/functions.lua +++ b/[esx]/es_extended/server/functions.lua @@ -176,6 +176,7 @@ function Core.SavePlayer(xPlayer, cb) }, function(affectedRows) if affectedRows == 1 then print(('[^2INFO^7] Saved player ^5"%s^7"'):format(xPlayer.name)) + TriggerEvent('esx:playerSaved', xPlayer.playerId, xPlayer) end if cb then cb() end end) @@ -258,14 +259,28 @@ function ESX.RegisterUsableItem(item, cb) Core.UsableItemsCallbacks[item] = cb end -function ESX.UseItem(source, item, data) +function ESX.UseItem(source, item, ...) if ESX.Items[item] then - Core.UsableItemsCallbacks[item](source, item, data) + Core.UsableItemsCallbacks[item](source, item, ...) else print(('[^3WARNING^7] Item ^5"%s"^7 was used but does not exist!'):format(item)) end end +function ESX.RegisterPlayerFunctionOverrides(index,overrides) + Core.PlayerFunctionOverrides[index] = overrides +end + +function ESX.SetPlayerFunctionOverride(index) + if not index + or not Core.PlayerFunctionOverrides[index] + then + return print('[^3WARNING^7] No valid index provided.') + end + + Config.PlayerFunctionOverride = index +end + function ESX.GetItemLabel(item) if ESX.Items[item] then return ESX.Items[item].label diff --git a/[esx]/es_extended/server/main.lua b/[esx]/es_extended/server/main.lua index 45714a7a..195f5180 100644 --- a/[esx]/es_extended/server/main.lua +++ b/[esx]/es_extended/server/main.lua @@ -1,625 +1,684 @@ SetMapName('San Andreas') SetGameType('ESX Legacy') - + local newPlayer = 'INSERT INTO `users` SET `accounts` = ?, `identifier` = ?, `group` = ?' local loadPlayer = 'SELECT `accounts`, `job`, `job_grade`, `group`, `position`, `inventory`, `skin`, `loadout`' if Config.Multichar then - newPlayer = newPlayer..', `firstname` = ?, `lastname` = ?, `dateofbirth` = ?, `sex` = ?, `height` = ?' + newPlayer = newPlayer .. ', `firstname` = ?, `lastname` = ?, `dateofbirth` = ?, `sex` = ?, `height` = ?' end if Config.Multichar or Config.Identity then - loadPlayer = loadPlayer..', `firstname`, `lastname`, `dateofbirth`, `sex`, `height`' + loadPlayer = loadPlayer .. ', `firstname`, `lastname`, `dateofbirth`, `sex`, `height`' end -loadPlayer = loadPlayer..' FROM `users` WHERE identifier = ?' +loadPlayer = loadPlayer .. ' FROM `users` WHERE identifier = ?' if Config.Multichar then - AddEventHandler('esx:onPlayerJoined', function(src, char, data) - while not next(ESX.Jobs) do Wait(50) end + AddEventHandler('esx:onPlayerJoined', function(src, char, data) + while not next(ESX.Jobs) do + Wait(50) + end - if not ESX.Players[src] then - local identifier = char..':'..ESX.GetIdentifier(src) - if data then - createESXPlayer(identifier, src, data) - else - loadESXPlayer(identifier, src, false) - end - end - end) + if not ESX.Players[src] then + local identifier = char .. ':' .. ESX.GetIdentifier(src) + if data then + createESXPlayer(identifier, src, data) + else + loadESXPlayer(identifier, src, false) + end + end + end) else - RegisterNetEvent('esx:onPlayerJoined') - AddEventHandler('esx:onPlayerJoined', function() - while not next(ESX.Jobs) do Wait(50) end + RegisterNetEvent('esx:onPlayerJoined') + AddEventHandler('esx:onPlayerJoined', function() + local _source = source + while not next(ESX.Jobs) do + Wait(50) + end - if not ESX.Players[source] then - onPlayerJoined(source) - end - end) + if not ESX.Players[_source] then + onPlayerJoined(_source) + end + end) end function onPlayerJoined(playerId) - local identifier = ESX.GetIdentifier(playerId) - if identifier then - if ESX.GetPlayerFromIdentifier(identifier) then - DropPlayer(playerId, ('there was an error loading your character!\nError code: identifier-active-ingame\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same Rockstar account.\n\nYour Rockstar identifier: %s'):format(identifier)) - else - local result = MySQL.scalar.await('SELECT 1 FROM users WHERE identifier = ?', { identifier }) - if result then - loadESXPlayer(identifier, playerId, false) - else - createESXPlayer(identifier, playerId) - end - end - else - DropPlayer(playerId, 'there was an error loading your character!\nError code: identifier-missing-ingame\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') - end + local identifier = ESX.GetIdentifier(playerId) + if identifier then + if ESX.GetPlayerFromIdentifier(identifier) then + DropPlayer(playerId, + ('there was an error loading your character!\nError code: identifier-active-ingame\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same Rockstar account.\n\nYour Rockstar identifier: %s'):format( + identifier)) + else + local result = MySQL.scalar.await('SELECT 1 FROM users WHERE identifier = ?', {identifier}) + if result then + loadESXPlayer(identifier, playerId, false) + else + createESXPlayer(identifier, playerId) + end + end + else + DropPlayer(playerId, + 'there was an error loading your character!\nError code: identifier-missing-ingame\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') + end end function createESXPlayer(identifier, playerId, data) - local accounts = {} + local accounts = {} - for account,money in pairs(Config.StartingAccountMoney) do - accounts[account] = money - end + for account, money in pairs(Config.StartingAccountMoney) do + accounts[account] = money + end - if Core.IsPlayerAdmin(playerId) then - print(('^2[INFO] ^0 Player ^5%s ^0Has been granted admin permissions via ^5Ace Perms.^7'):format(playerId)) - defaultGroup = "admin" - else - defaultGroup = "user" - end + if Core.IsPlayerAdmin(playerId) then + print(('^2[INFO] ^0 Player ^5%s ^0Has been granted admin permissions via ^5Ace Perms.^7'):format(playerId)) + defaultGroup = "admin" + else + defaultGroup = "user" + end - if not Config.Multichar then - MySQL.prepare(newPlayer, { json.encode(accounts), identifier, defaultGroup }, function() - loadESXPlayer(identifier, playerId, true) - end) - else - MySQL.prepare(newPlayer, { - json.encode(accounts), - identifier, - defaultGroup, - data.firstname, - data.lastname, - data.dateofbirth, - data.sex, - data.height - }, function() - loadESXPlayer(identifier, playerId, true) - end) - end + if not Config.Multichar then + MySQL.prepare(newPlayer, {json.encode(accounts), identifier, defaultGroup}, function() + loadESXPlayer(identifier, playerId, true) + end) + else + MySQL.prepare(newPlayer, + {json.encode(accounts), identifier, defaultGroup, data.firstname, data.lastname, data.dateofbirth, data.sex, + data.height}, function() + loadESXPlayer(identifier, playerId, true) + end) + end end if not Config.Multichar then - AddEventHandler('playerConnecting', function(name, setCallback, deferrals) - deferrals.defer() - local playerId = source - local identifier = ESX.GetIdentifier(playerId) + AddEventHandler('playerConnecting', function(name, setCallback, deferrals) + deferrals.defer() + local playerId = source + local identifier = ESX.GetIdentifier(playerId) - if identifier then - if ESX.GetPlayerFromIdentifier(identifier) then - deferrals.done(('There was an error loading your character!\nError code: identifier-active\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same account.\n\nYour identifier: %s'):format(identifier)) - else - deferrals.done() - end - else - deferrals.done('There was an error loading your character!\nError code: identifier-missing\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') - end - end) + if identifier then + if ESX.GetPlayerFromIdentifier(identifier) then + deferrals.done( + ('There was an error loading your character!\nError code: identifier-active\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same account.\n\nYour identifier: %s'):format( + identifier)) + else + deferrals.done() + end + else + deferrals.done( + 'There was an error loading your character!\nError code: identifier-missing\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') + end + end) end function loadESXPlayer(identifier, playerId, isNew) - local userData = { - accounts = {}, - inventory = {}, - job = {}, - loadout = {}, - playerName = GetPlayerName(playerId), - weight = 0 - } + local userData = { + accounts = {}, + inventory = {}, + job = {}, + loadout = {}, + playerName = GetPlayerName(playerId), + weight = 0 + } - local result = MySQL.prepare.await(loadPlayer, { identifier }) - local job, grade, jobObject, gradeObject = result.job, tostring(result.job_grade) - local foundAccounts, foundItems = {}, {} + local result = MySQL.prepare.await(loadPlayer, {identifier}) + local job, grade, jobObject, gradeObject = result.job, tostring(result.job_grade) + local foundAccounts, foundItems = {}, {} - -- Accounts - if result.accounts and result.accounts ~= '' then - local accounts = json.decode(result.accounts) + -- Accounts + if result.accounts and result.accounts ~= '' then + local accounts = json.decode(result.accounts) - for account,money in pairs(accounts) do - foundAccounts[account] = money - end - end + for account, money in pairs(accounts) do + foundAccounts[account] = money + end + end - for account,label in pairs(Config.Accounts) do - table.insert(userData.accounts, { - name = account, - money = foundAccounts[account] or Config.StartingAccountMoney[account] or 0, - label = label - }) - end + for account, label in pairs(Config.Accounts) do + table.insert(userData.accounts, { + name = account, + money = foundAccounts[account] or Config.StartingAccountMoney[account] or 0, + label = label + }) + end - -- Job - if ESX.DoesJobExist(job, grade) then - jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - else - print(('[^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(identifier, job, grade)) - job, grade = 'unemployed', '0' - jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - end + -- Job + if ESX.DoesJobExist(job, grade) then + jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + else + print(('[^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(identifier, job, grade)) + job, grade = 'unemployed', '0' + jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + end - userData.job.id = jobObject.id - userData.job.name = jobObject.name - userData.job.label = jobObject.label + userData.job.id = jobObject.id + userData.job.name = jobObject.name + userData.job.label = jobObject.label - userData.job.grade = tonumber(grade) - userData.job.grade_name = gradeObject.name - userData.job.grade_label = gradeObject.label - userData.job.grade_salary = gradeObject.salary + userData.job.grade = tonumber(grade) + userData.job.grade_name = gradeObject.name + userData.job.grade_label = gradeObject.label + userData.job.grade_salary = gradeObject.salary userData.job.onDuty = Config.OnDuty - userData.job.skin_male = {} - userData.job.skin_female = {} + userData.job.skin_male = {} + userData.job.skin_female = {} - if gradeObject.skin_male then userData.job.skin_male = json.decode(gradeObject.skin_male) end - if gradeObject.skin_female then userData.job.skin_female = json.decode(gradeObject.skin_female) end + if gradeObject.skin_male then + userData.job.skin_male = json.decode(gradeObject.skin_male) + end + if gradeObject.skin_female then + userData.job.skin_female = json.decode(gradeObject.skin_female) + end - -- Inventory - if not Config.OxInventory then - if result.inventory and result.inventory ~= '' then - local inventory = json.decode(result.inventory) + -- Inventory + if not Config.OxInventory then + if result.inventory and result.inventory ~= '' then + local inventory = json.decode(result.inventory) - for name,count in pairs(inventory) do - local item = ESX.Items[name] + for name, count in pairs(inventory) do + local item = ESX.Items[name] - if item then - foundItems[name] = count - else - print(('[^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, identifier)) - end - end - end + if item then + foundItems[name] = count + else + print(('[^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, identifier)) + end + end + end - for name,item in pairs(ESX.Items) do - local count = foundItems[name] or 0 - if count > 0 then userData.weight = userData.weight + (item.weight * count) end + for name, item in pairs(ESX.Items) do + local count = foundItems[name] or 0 + if count > 0 then + userData.weight = userData.weight + (item.weight * count) + end - table.insert(userData.inventory, { - name = name, - count = count, - label = item.label, - weight = item.weight, - usable = Core.UsableItemsCallbacks[name] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - end + table.insert(userData.inventory, { + name = name, + count = count, + label = item.label, + weight = item.weight, + usable = Core.UsableItemsCallbacks[name] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) + end - table.sort(userData.inventory, function(a, b) - return a.label < b.label - end) - else - if result.inventory and result.inventory ~= '' then - userData.inventory = json.decode(result.inventory) - else - userData.inventory = {} - end - end + table.sort(userData.inventory, function(a, b) + return a.label < b.label + end) + else + if result.inventory and result.inventory ~= '' then + userData.inventory = json.decode(result.inventory) + else + userData.inventory = {} + end + end - -- Group - if result.group then - if result.group == "superadmin" then - userData.group = "admin" - else - userData.group = result.group - end - else - userData.group = 'user' - end + -- Group + if result.group then + if result.group == "superadmin" then + userData.group = "admin" + else + userData.group = result.group + end + else + userData.group = 'user' + end - -- Loadout - if not Config.OxInventory then - if result.loadout and result.loadout ~= '' then - local loadout = json.decode(result.loadout) + -- Loadout + if not Config.OxInventory then + if result.loadout and result.loadout ~= '' then + local loadout = json.decode(result.loadout) - for name,weapon in pairs(loadout) do - local label = ESX.GetWeaponLabel(name) + for name, weapon in pairs(loadout) do + local label = ESX.GetWeaponLabel(name) - if label then - if not weapon.components then weapon.components = {} end - if not weapon.tintIndex then weapon.tintIndex = 0 end + if label then + if not weapon.components then + weapon.components = {} + end + if not weapon.tintIndex then + weapon.tintIndex = 0 + end - table.insert(userData.loadout, { - name = name, - ammo = weapon.ammo, - label = label, - components = weapon.components, - tintIndex = weapon.tintIndex - }) - end - end - end - end + table.insert(userData.loadout, { + name = name, + ammo = weapon.ammo, + label = label, + components = weapon.components, + tintIndex = weapon.tintIndex + }) + end + end + end + end - -- Position - if result.position and result.position ~= '' then - userData.coords = json.decode(result.position) - else - print('[^3WARNING^7] Column ^5"position"^0 in ^5"users"^0 table is missing required default value. Using backup coords, fix your database.') - userData.coords = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8} - end + -- Position + if result.position and result.position ~= '' then + userData.coords = json.decode(result.position) + else + print( + '[^3WARNING^7] Column ^5"position"^0 in ^5"users"^0 table is missing required default value. Using backup coords, fix your database.') + userData.coords = { + x = -269.4, + y = -955.3, + z = 31.2, + heading = 205.8 + } + end - -- Skin - if result.skin and result.skin ~= '' then - userData.skin = json.decode(result.skin) - else - if userData.sex == 'f' then userData.skin = {sex=1} else userData.skin = {sex=0} end - end + -- Skin + if result.skin and result.skin ~= '' then + userData.skin = json.decode(result.skin) + else + if userData.sex == 'f' then + userData.skin = { + sex = 1 + } + else + userData.skin = { + sex = 0 + } + end + end - -- Identity - if result.firstname and result.firstname ~= '' then - userData.firstname = result.firstname - userData.lastname = result.lastname - userData.playerName = userData.firstname..' '..userData.lastname - if result.dateofbirth then userData.dateofbirth = result.dateofbirth end - if result.sex then userData.sex = result.sex end - if result.height then userData.height = result.height end - end + -- Identity + if result.firstname and result.firstname ~= '' then + userData.firstname = result.firstname + userData.lastname = result.lastname + userData.playerName = userData.firstname .. ' ' .. userData.lastname + if result.dateofbirth then + userData.dateofbirth = result.dateofbirth + end + if result.sex then + userData.sex = result.sex + end + if result.height then + userData.height = result.height + end + end - local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.weight, userData.job, userData.loadout, userData.playerName, userData.coords) - ESX.Players[playerId] = xPlayer + local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, + userData.weight, userData.job, userData.loadout, userData.playerName, userData.coords) + ESX.Players[playerId] = xPlayer - if userData.firstname then - xPlayer.set('firstName', userData.firstname) - xPlayer.set('lastName', userData.lastname) - if userData.dateofbirth then xPlayer.set('dateofbirth', userData.dateofbirth) end - if userData.sex then xPlayer.set('sex', userData.sex) end - if userData.height then xPlayer.set('height', userData.height) end - end + if userData.firstname then + xPlayer.set('firstName', userData.firstname) + xPlayer.set('lastName', userData.lastname) + if userData.dateofbirth then + xPlayer.set('dateofbirth', userData.dateofbirth) + end + if userData.sex then + xPlayer.set('sex', userData.sex) + end + if userData.height then + xPlayer.set('height', userData.height) + end + end - TriggerEvent('esx:playerLoaded', playerId, xPlayer, isNew) + TriggerEvent('esx:playerLoaded', playerId, xPlayer, isNew) - xPlayer.triggerEvent('esx:playerLoaded', { - accounts = xPlayer.getAccounts(), - coords = xPlayer.getCoords(), - identifier = xPlayer.getIdentifier(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - maxWeight = xPlayer.getMaxWeight(), - money = xPlayer.getMoney(), - dead = false - }, isNew, userData.skin) + xPlayer.triggerEvent('esx:playerLoaded', { + accounts = xPlayer.getAccounts(), + coords = xPlayer.getCoords(), + identifier = xPlayer.getIdentifier(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + maxWeight = xPlayer.getMaxWeight(), + money = xPlayer.getMoney(), + dead = false + }, isNew, userData.skin) - if not Config.OxInventory then - xPlayer.triggerEvent('esx:createMissingPickups', Core.Pickups) - else - exports.ox_inventory:setPlayerInventory(xPlayer, userData.inventory) - end + if not Config.OxInventory then + xPlayer.triggerEvent('esx:createMissingPickups', Core.Pickups) + else + exports.ox_inventory:setPlayerInventory(xPlayer, userData.inventory) + end - xPlayer.triggerEvent('esx:registerSuggestions', Core.RegisteredCommands) - print(('[^2INFO^0] Player ^5"%s" ^0has connected to the server. ID: ^5%s^7'):format(xPlayer.getName(), playerId)) + xPlayer.triggerEvent('esx:registerSuggestions', Core.RegisteredCommands) + print(('[^2INFO^0] Player ^5"%s" ^0has connected to the server. ID: ^5%s^7'):format(xPlayer.getName(), playerId)) end AddEventHandler('chatMessage', function(playerId, author, message) - local xPlayer = ESX.GetPlayerFromId(playerId) - if message:sub(1, 1) == '/' and playerId > 0 then - CancelEvent() - local commandName = message:sub(1):gmatch("%w+")() - xPlayer.showNotification(_U('commanderror_invalidcommand', commandName)) - end + local xPlayer = ESX.GetPlayerFromId(playerId) + if message:sub(1, 1) == '/' and playerId > 0 then + CancelEvent() + local commandName = message:sub(1):gmatch("%w+")() + xPlayer.showNotification(_U('commanderror_invalidcommand', commandName)) + end end) AddEventHandler('playerDropped', function(reason) - local playerId = source - local xPlayer = ESX.GetPlayerFromId(playerId) + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) - if xPlayer then - TriggerEvent('esx:playerDropped', playerId, reason) + if xPlayer then + TriggerEvent('esx:playerDropped', playerId, reason) - Core.SavePlayer(xPlayer, function() - ESX.Players[playerId] = nil - end) - end + Core.SavePlayer(xPlayer, function() + ESX.Players[playerId] = nil + end) + end end) -if Config.Multichar then - AddEventHandler('esx:playerLogout', function(playerId) - local xPlayer = ESX.GetPlayerFromId(playerId) - if xPlayer then - TriggerEvent('esx:playerDropped', playerId) +AddEventHandler('esx:playerLogout', function(playerId, cb) + local xPlayer = ESX.GetPlayerFromId(playerId) + if xPlayer then + TriggerEvent('esx:playerDropped', playerId) - Core.SavePlayer(xPlayer, function() - ESX.Players[playerId] = nil - end) - end - TriggerClientEvent("esx:onPlayerLogout", playerId) - end) -end + Core.SavePlayer(xPlayer, function() + ESX.Players[playerId] = nil + if cb then + cb() + end + end) + end + TriggerClientEvent("esx:onPlayerLogout", playerId) +end) RegisterNetEvent('esx:updateCoords') AddEventHandler('esx:updateCoords', function(coords) - local xPlayer = ESX.GetPlayerFromId(source) + local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer then - xPlayer.updateCoords(coords) - end + if xPlayer then + xPlayer.updateCoords(coords) + end end) if not Config.OxInventory then - RegisterNetEvent('esx:updateWeaponAmmo') - AddEventHandler('esx:updateWeaponAmmo', function(weaponName, ammoCount) - local xPlayer = ESX.GetPlayerFromId(source) + RegisterNetEvent('esx:updateWeaponAmmo') + AddEventHandler('esx:updateWeaponAmmo', function(weaponName, ammoCount) + local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer then - xPlayer.updateWeaponAmmo(weaponName, ammoCount) - end - end) + if xPlayer then + xPlayer.updateWeaponAmmo(weaponName, ammoCount) + end + end) - RegisterNetEvent('esx:giveInventoryItem') - AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) - local playerId = source - local sourceXPlayer = ESX.GetPlayerFromId(playerId) - local targetXPlayer = ESX.GetPlayerFromId(target) + RegisterNetEvent('esx:giveInventoryItem') + AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) + local playerId = source + local sourceXPlayer = ESX.GetPlayerFromId(playerId) + local targetXPlayer = ESX.GetPlayerFromId(target) local distance = #(GetEntityCoords(GetPlayerPed(playerId)) - GetEntityCoords(GetPlayerPed(target))) - if not sourceXPlayer then return end - if not targetXPlayer then print("Cheating: " .. GetPlayerName(playerId)) return end - if distance > Config.DistanceGive then print("Cheating: " .. GetPlayerName(playerId)) return end + if not sourceXPlayer then + return + end + if not targetXPlayer then + print("Cheating: " .. GetPlayerName(playerId)) + return + end + if distance > Config.DistanceGive then + print("Cheating: " .. GetPlayerName(playerId)) + return + end + if type == 'item_standard' then + local sourceItem = sourceXPlayer.getInventoryItem(itemName) - if type == 'item_standard' then - local sourceItem = sourceXPlayer.getInventoryItem(itemName) + if itemCount > 0 and sourceItem.count >= itemCount then + if targetXPlayer.canCarryItem(itemName, itemCount) then + sourceXPlayer.removeInventoryItem(itemName, itemCount) + targetXPlayer.addInventoryItem(itemName, itemCount) - if itemCount > 0 and sourceItem.count >= itemCount then - if targetXPlayer.canCarryItem(itemName, itemCount) then - sourceXPlayer.removeInventoryItem(itemName, itemCount) - targetXPlayer.addInventoryItem (itemName, itemCount) + sourceXPlayer.showNotification(_U('gave_item', itemCount, sourceItem.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_item', itemCount, sourceItem.label, sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('ex_inv_lim', targetXPlayer.name)) + end + else + sourceXPlayer.showNotification(_U('imp_invalid_quantity')) + end + elseif type == 'item_account' then + if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then + sourceXPlayer.removeAccountMoney(itemName, itemCount) + targetXPlayer.addAccountMoney(itemName, itemCount) - sourceXPlayer.showNotification(_U('gave_item', itemCount, sourceItem.label, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_item', itemCount, sourceItem.label, sourceXPlayer.name)) - else - sourceXPlayer.showNotification(_U('ex_inv_lim', targetXPlayer.name)) - end - else - sourceXPlayer.showNotification(_U('imp_invalid_quantity')) - end - elseif type == 'item_account' then - if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then - sourceXPlayer.removeAccountMoney(itemName, itemCount) - targetXPlayer.addAccountMoney (itemName, itemCount) - - sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName], targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName], sourceXPlayer.name)) - else - sourceXPlayer.showNotification(_U('imp_invalid_amount')) - end - elseif type == 'item_weapon' then - if sourceXPlayer.hasWeapon(itemName) then - local weaponLabel = ESX.GetWeaponLabel(itemName) - if not targetXPlayer.hasWeapon(itemName) then - local _, weapon = sourceXPlayer.getWeapon(itemName) - local _, weaponObject = ESX.GetWeapon(itemName) - itemCount = weapon.ammo - local weaponComponents = ESX.Table.Clone(weapon.components) - local weaponTint = weapon.tintIndex - if weaponTint then + sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), + Config.Accounts[itemName], targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), + Config.Accounts[itemName], sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('imp_invalid_amount')) + end + elseif type == 'item_weapon' then + if sourceXPlayer.hasWeapon(itemName) then + local weaponLabel = ESX.GetWeaponLabel(itemName) + if not targetXPlayer.hasWeapon(itemName) then + local _, weapon = sourceXPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) + itemCount = weapon.ammo + local weaponComponents = ESX.Table.Clone(weapon.components) + local weaponTint = weapon.tintIndex + if weaponTint then targetXPlayer.setWeaponTint(itemName, weaponTint) - end - if weaponComponents then + end + if weaponComponents then for k, v in pairs(weaponComponents) do targetXPlayer.addWeaponComponent(itemName, v) end - end - sourceXPlayer.removeWeapon(itemName) - targetXPlayer.addWeapon(itemName, itemCount) + end + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) - if weaponObject.ammo and itemCount > 0 then - local ammoLabel = weaponObject.ammo.label - sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, ammoLabel, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, ammoLabel, sourceXPlayer.name)) - else - sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) - end - else - sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) - targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) - end - end - elseif type == 'item_ammo' then - if sourceXPlayer.hasWeapon(itemName) then - local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + if weaponObject.ammo and itemCount > 0 then + local ammoLabel = weaponObject.ammo.label + sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, ammoLabel, + targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, ammoLabel, + sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) + end + else + sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) + targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) + end + end + elseif type == 'item_ammo' then + if sourceXPlayer.hasWeapon(itemName) then + local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) - if targetXPlayer.hasWeapon(itemName) then - local _, weaponObject = ESX.GetWeapon(itemName) + if targetXPlayer.hasWeapon(itemName) then + local _, weaponObject = ESX.GetWeapon(itemName) - if weaponObject.ammo then - local ammoLabel = weaponObject.ammo.label + if weaponObject.ammo then + local ammoLabel = weaponObject.ammo.label - if weapon.ammo >= itemCount then - sourceXPlayer.removeWeaponAmmo(itemName, itemCount) - targetXPlayer.addWeaponAmmo(itemName, itemCount) + if weapon.ammo >= itemCount then + sourceXPlayer.removeWeaponAmmo(itemName, itemCount) + targetXPlayer.addWeaponAmmo(itemName, itemCount) - sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, ammoLabel, weapon.label, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, ammoLabel, weapon.label, sourceXPlayer.name)) - end - end - else - sourceXPlayer.showNotification(_U('gave_weapon_noweapon', targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_noweapon', sourceXPlayer.name, weapon.label)) - end - end - end - end) + sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, ammoLabel, weapon.label, + targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, ammoLabel, + weapon.label, sourceXPlayer.name)) + end + end + else + sourceXPlayer.showNotification(_U('gave_weapon_noweapon', targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_noweapon', sourceXPlayer.name, weapon.label)) + end + end + end + end) - RegisterNetEvent('esx:removeInventoryItem') - AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) - local playerId = source - local xPlayer = ESX.GetPlayerFromId(source) + RegisterNetEvent('esx:removeInventoryItem') + AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) + local playerId = source + local xPlayer = ESX.GetPlayerFromId(source) - if type == 'item_standard' then - if itemCount == nil or itemCount < 1 then - xPlayer.showNotification(_U('imp_invalid_quantity')) - else - local xItem = xPlayer.getInventoryItem(itemName) + if type == 'item_standard' then + if itemCount == nil or itemCount < 1 then + xPlayer.showNotification(_U('imp_invalid_quantity')) + else + local xItem = xPlayer.getInventoryItem(itemName) - if (itemCount > xItem.count or xItem.count < 1) then - xPlayer.showNotification(_U('imp_invalid_quantity')) - else - xPlayer.removeInventoryItem(itemName, itemCount) - local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(xItem.label, itemCount) - ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, playerId) - xPlayer.showNotification(_U('threw_standard', itemCount, xItem.label)) - end - end - elseif type == 'item_account' then - if itemCount == nil or itemCount < 1 then - xPlayer.showNotification(_U('imp_invalid_amount')) - else - local account = xPlayer.getAccount(itemName) + if (itemCount > xItem.count or xItem.count < 1) then + xPlayer.showNotification(_U('imp_invalid_quantity')) + else + xPlayer.removeInventoryItem(itemName, itemCount) + local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(xItem.label, itemCount) + ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_standard', itemCount, xItem.label)) + end + end + elseif type == 'item_account' then + if itemCount == nil or itemCount < 1 then + xPlayer.showNotification(_U('imp_invalid_amount')) + else + local account = xPlayer.getAccount(itemName) - if (itemCount > account.money or account.money < 1) then - xPlayer.showNotification(_U('imp_invalid_amount')) - else - xPlayer.removeAccountMoney(itemName, itemCount) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(account.label, _U('locale_currency', ESX.Math.GroupDigits(itemCount))) - ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, playerId) - xPlayer.showNotification(_U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) - end - end - elseif type == 'item_weapon' then - itemName = string.upper(itemName) + if (itemCount > account.money or account.money < 1) then + xPlayer.showNotification(_U('imp_invalid_amount')) + else + xPlayer.removeAccountMoney(itemName, itemCount) + local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(account.label, _U('locale_currency', ESX.Math + .GroupDigits(itemCount))) + ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_account', ESX.Math.GroupDigits(itemCount), + string.lower(account.label))) + end + end + elseif type == 'item_weapon' then + itemName = string.upper(itemName) - if xPlayer.hasWeapon(itemName) then - local _, weapon = xPlayer.getWeapon(itemName) - local _, weaponObject = ESX.GetWeapon(itemName) - local components, pickupLabel = ESX.Table.Clone(weapon.components) - xPlayer.removeWeapon(itemName) + if xPlayer.hasWeapon(itemName) then + local _, weapon = xPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) + local components, pickupLabel = ESX.Table.Clone(weapon.components) + xPlayer.removeWeapon(itemName) - if weaponObject.ammo and weapon.ammo > 0 then - local ammoLabel = weaponObject.ammo.label - pickupLabel = ('~y~%s~s~ [~g~%s~s~ %s]'):format(weapon.label, weapon.ammo, ammoLabel) - xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo, ammoLabel)) - else - pickupLabel = ('~y~%s~s~'):format(weapon.label) - xPlayer.showNotification(_U('threw_weapon', weapon.label)) - end + if weaponObject.ammo and weapon.ammo > 0 then + local ammoLabel = weaponObject.ammo.label + pickupLabel = ('~y~%s~s~ [~g~%s~s~ %s]'):format(weapon.label, weapon.ammo, ammoLabel) + xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo, ammoLabel)) + else + pickupLabel = ('~y~%s~s~'):format(weapon.label) + xPlayer.showNotification(_U('threw_weapon', weapon.label)) + end - ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, components, weapon.tintIndex) - end - end - end) + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, components, + weapon.tintIndex) + end + end + end) + RegisterNetEvent('esx:useItem') + AddEventHandler('esx:useItem', function(itemName) + local xPlayer = ESX.GetPlayerFromId(source) + local count = xPlayer.getInventoryItem(itemName).count - RegisterNetEvent('esx:useItem') - AddEventHandler('esx:useItem', function(itemName) - local xPlayer = ESX.GetPlayerFromId(source) - local count = xPlayer.getInventoryItem(itemName).count + if count > 0 then + ESX.UseItem(source, itemName) + else + xPlayer.showNotification(_U('act_imp')) + end + end) - if count > 0 then - ESX.UseItem(source, itemName) - else - xPlayer.showNotification(_U('act_imp')) - end - end) + RegisterNetEvent('esx:onPickup') + AddEventHandler('esx:onPickup', function(pickupId) + local pickup, xPlayer, success = Core.Pickups[pickupId], ESX.GetPlayerFromId(source) - RegisterNetEvent('esx:onPickup') - AddEventHandler('esx:onPickup', function(pickupId) - local pickup, xPlayer, success = Core.Pickups[pickupId], ESX.GetPlayerFromId(source) + if pickup then + if pickup.type == 'item_standard' then + if xPlayer.canCarryItem(pickup.name, pickup.count) then + xPlayer.addInventoryItem(pickup.name, pickup.count) + success = true + else + xPlayer.showNotification(_U('threw_cannot_pickup')) + end + elseif pickup.type == 'item_account' then + success = true + xPlayer.addAccountMoney(pickup.name, pickup.count) + elseif pickup.type == 'item_weapon' then + if xPlayer.hasWeapon(pickup.name) then + xPlayer.showNotification(_U('threw_weapon_already')) + else + success = true + xPlayer.addWeapon(pickup.name, pickup.count) + xPlayer.setWeaponTint(pickup.name, pickup.tintIndex) - if pickup then - if pickup.type == 'item_standard' then - if xPlayer.canCarryItem(pickup.name, pickup.count) then - xPlayer.addInventoryItem(pickup.name, pickup.count) - success = true - else - xPlayer.showNotification(_U('threw_cannot_pickup')) - end - elseif pickup.type == 'item_account' then - success = true - xPlayer.addAccountMoney(pickup.name, pickup.count) - elseif pickup.type == 'item_weapon' then - if xPlayer.hasWeapon(pickup.name) then - xPlayer.showNotification(_U('threw_weapon_already')) - else - success = true - xPlayer.addWeapon(pickup.name, pickup.count) - xPlayer.setWeaponTint(pickup.name, pickup.tintIndex) + for k, v in ipairs(pickup.components) do + xPlayer.addWeaponComponent(pickup.name, v) + end + end + end - for k,v in ipairs(pickup.components) do - xPlayer.addWeaponComponent(pickup.name, v) - end - end - end - - if success then - Core.Pickups[pickupId] = nil - TriggerClientEvent('esx:removePickup', -1, pickupId) - end - end - end) + if success then + Core.Pickups[pickupId] = nil + TriggerClientEvent('esx:removePickup', -1, pickupId) + end + end + end) end ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) + local xPlayer = ESX.GetPlayerFromId(source) - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - money = xPlayer.getMoney() - }) + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + money = xPlayer.getMoney() + }) end) ESX.RegisterServerCallback('esx:isUserAdmin', function(source, cb) - cb(Core.IsPlayerAdmin(source)) + cb(Core.IsPlayerAdmin(source)) end) ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target) - local xPlayer = ESX.GetPlayerFromId(target) + local xPlayer = ESX.GetPlayerFromId(target) - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - money = xPlayer.getMoney() - }) + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + money = xPlayer.getMoney() + }) end) ESX.RegisterServerCallback('esx:getPlayerNames', function(source, cb, players) - players[source] = nil + players[source] = nil - for playerId,v in pairs(players) do - local xPlayer = ESX.GetPlayerFromId(playerId) + for playerId, v in pairs(players) do + local xPlayer = ESX.GetPlayerFromId(playerId) - if xPlayer then - players[playerId] = xPlayer.getName() - else - players[playerId] = nil - end - end + if xPlayer then + players[playerId] = xPlayer.getName() + else + players[playerId] = nil + end + end - cb(players) + cb(players) end) AddEventHandler('txAdmin:events:scheduledRestart', function(eventData) - if eventData.secondsRemaining == 60 then - CreateThread(function() - Wait(50000) - Core.SavePlayers() - end) - end + if eventData.secondsRemaining == 60 then + CreateThread(function() + Wait(50000) + Core.SavePlayers() + end) + end end) RegisterNetEvent('esx:setDuty') AddEventHandler('esx:setDuty', function(bool) local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.job.onDuty == bool then return end - + if xPlayer.job.onDuty == bool then + return + end + if bool then xPlayer.setDuty(true) xPlayer.triggerEvent('esx:showNotification', _U('started_duty'))