diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..f11a345e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "[esx_addons]/esx_multicharacter"] + path = [esx_addons]/esx_multicharacter + url = https://github.com/thelindat/esx_multicharacter.git diff --git a/[esx]/es_extended/README.md b/[esx]/es_extended/README.md index ad9167a0..33971372 100644 --- a/[esx]/es_extended/README.md +++ b/[esx]/es_extended/README.md @@ -21,7 +21,6 @@ Many more resources are included in this repository, or you can browse the [ESX #### Optimisation - Utilise compile-time jenkins hashing over the GetHashKey native -- Update old MySQL queries to use MySQL.store to improve performance, especially during player saving - Several loops will now sleep when their tasks are not necessary to perform - Improved support when using ESX Identity to reduce events and queries during player login - Support for the latest weapons and components diff --git a/[esx]/es_extended/client/common.lua b/[esx]/es_extended/client/common.lua index 26c0ed40..441cee8e 100644 --- a/[esx]/es_extended/client/common.lua +++ b/[esx]/es_extended/client/common.lua @@ -2,6 +2,6 @@ AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) end) -function getSharedObject() +exports('getSharedObject', function() return ESX -end +end) diff --git a/[esx]/es_extended/client/functions.lua b/[esx]/es_extended/client/functions.lua index acf7a802..ee6e2cf6 100644 --- a/[esx]/es_extended/client/functions.lua +++ b/[esx]/es_extended/client/functions.lua @@ -1,9 +1,10 @@ ESX = {} +Core = {} ESX.PlayerData = {} ESX.PlayerLoaded = false -ESX.CurrentRequestId = 0 -ESX.ServerCallbacks = {} -ESX.TimeoutCallbacks = {} +Core.CurrentRequestId = 0 +Core.ServerCallbacks = {} +Core.TimeoutCallbacks = {} ESX.UI = {} ESX.UI.HUD = {} @@ -21,15 +22,15 @@ ESX.Scaleform.Utils = {} ESX.Streaming = {} ESX.SetTimeout = function(msec, cb) - table.insert(ESX.TimeoutCallbacks, { + table.insert(Core.TimeoutCallbacks, { time = GetGameTimer() + msec, cb = cb }) - return #ESX.TimeoutCallbacks + return #Core.TimeoutCallbacks end ESX.ClearTimeout = function(i) - ESX.TimeoutCallbacks[i] = nil + Core.TimeoutCallbacks[i] = nil end ESX.IsPlayerLoaded = function() @@ -86,14 +87,14 @@ ESX.ShowFloatingHelpNotification = function(msg, coords) end ESX.TriggerServerCallback = function(name, cb, ...) - ESX.ServerCallbacks[ESX.CurrentRequestId] = cb + Core.ServerCallbacks[Core.CurrentRequestId] = cb - TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) + TriggerServerEvent('esx:triggerServerCallback', name, Core.CurrentRequestId, ...) - if ESX.CurrentRequestId < 65535 then - ESX.CurrentRequestId = ESX.CurrentRequestId + 1 + if Core.CurrentRequestId < 65535 then + Core.CurrentRequestId = Core.CurrentRequestId + 1 else - ESX.CurrentRequestId = 0 + Core.CurrentRequestId = 0 end end @@ -849,7 +850,7 @@ ESX.ShowInventory = function() players[GetPlayerServerId(playerNearby)] = true end - ESX.TriggerServerCallback('esx:getPlayerNames', function(returnedPlayers) + Core.TriggerServerCallback('esx:getPlayerNames', function(returnedPlayers) for playerId,playerName in pairs(returnedPlayers) do table.insert(elements, { label = playerName, @@ -989,8 +990,8 @@ end RegisterNetEvent('esx:serverCallback') AddEventHandler('esx:serverCallback', function(requestId, ...) - ESX.ServerCallbacks[requestId](...) - ESX.ServerCallbacks[requestId] = nil + Core.ServerCallbacks[requestId](...) + Core.ServerCallbacks[requestId] = nil end) RegisterNetEvent('esx:showNotification') @@ -1012,13 +1013,13 @@ end) Citizen.CreateThread(function() while true do local sleep = 100 - if #ESX.TimeoutCallbacks > 0 then + if #Core.TimeoutCallbacks > 0 then local currTime = GetGameTimer() sleep = 0 - for i=1, #ESX.TimeoutCallbacks, 1 do - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil + for i=1, #Core.TimeoutCallbacks, 1 do + if currTime >= Core.TimeoutCallbacks[i].time then + Core.TimeoutCallbacks[i].cb() + Core.TimeoutCallbacks[i] = nil end end end diff --git a/[esx]/es_extended/client/main.lua b/[esx]/es_extended/client/main.lua index c464139f..75b66a40 100644 --- a/[esx]/es_extended/client/main.lua +++ b/[esx]/es_extended/client/main.lua @@ -32,15 +32,14 @@ AddEventHandler('esx:playerLoaded', function(xPlayer, isNew, skin) }, function() TriggerServerEvent('esx:onPlayerSpawn') TriggerEvent('esx:onPlayerSpawn') - TriggerEvent('playerSpawned') -- compatibility with old scripts TriggerEvent('esx:restoreLoadout') + if isNew then - if skin.sex == 0 then - TriggerEvent('skinchanger:loadDefaultModel', true) - else - TriggerEvent('skinchanger:loadDefaultModel', false) - end - elseif skin then TriggerEvent('skinchanger:loadSkin', skin) end + TriggerEvent('skinchanger:loadDefaultModel', skin.sex == 0) + elseif skin then + TriggerEvent('skinchanger:loadSkin', skin) + end + TriggerEvent('esx:loadingScreenOff') ShutdownLoadingScreen() ShutdownLoadingScreenNui() @@ -65,7 +64,7 @@ AddEventHandler('esx:playerLoaded', function(xPlayer, isNew, skin) local gradeLabel = ESX.PlayerData.job.grade_label ~= ESX.PlayerData.job.label and ESX.PlayerData.job.grade_label or '' if gradeLabel ~= '' then gradeLabel = ' - '..gradeLabel end - + ESX.UI.HUD.RegisterElement('job', #ESX.PlayerData.accounts, 0, jobTpl, { job_label = ESX.PlayerData.job.label, grade_label = gradeLabel @@ -83,10 +82,15 @@ end) RegisterNetEvent('esx:setMaxWeight') AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight end) -AddEventHandler('esx:onPlayerSpawn', function() - ESX.SetPlayerData('ped', PlayerPedId()) - ESX.SetPlayerData('dead', false) -end) +local function onPlayerSpawn() + if ESX.PlayerLoaded then + ESX.SetPlayerData('ped', PlayerPedId()) + ESX.SetPlayerData('dead', false) + end +end + +AddEventHandler('playerSpawned', onPlayerSpawn) +AddEventHandler('esx:onPlayerSpawn', onPlayerSpawn) AddEventHandler('esx:onPlayerDeath', function() ESX.SetPlayerData('ped', PlayerPedId()) @@ -282,7 +286,7 @@ end) RegisterNetEvent('esx:createMissingPickups') AddEventHandler('esx:createMissingPickups', function(missingPickups) - for pickupId,pickup in pairs(missingPickups) do + for pickupId, pickup in pairs(missingPickups) do TriggerEvent('esx:createPickup', pickupId, pickup.label, pickup.coords, pickup.type, pickup.name, pickup.components, pickup.tintIndex) end end) diff --git a/[esx]/es_extended/fxmanifest.lua b/[esx]/es_extended/fxmanifest.lua index 4ccf6a9c..e6fb3a74 100644 --- a/[esx]/es_extended/fxmanifest.lua +++ b/[esx]/es_extended/fxmanifest.lua @@ -15,7 +15,6 @@ shared_scripts { } server_scripts { - '@async/async.lua', '@mysql-async/lib/MySQL.lua', 'server/common.lua', @@ -69,16 +68,8 @@ files { 'html/img/accounts/money.png' } -exports { - 'getSharedObject' -} - -server_exports { - 'getSharedObject' -} - dependencies { - 'mysql-async', + 'oxmysql', 'async', 'spawnmanager', } diff --git a/[esx]/es_extended/server/classes/player.lua b/[esx]/es_extended/server/classes/player.lua index 148210b4..69f95f70 100644 --- a/[esx]/es_extended/server/classes/player.lua +++ b/[esx]/es_extended/server/classes/player.lua @@ -14,7 +14,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.variables = {} self.weight = weight self.maxWeight = Config.MaxWeight - if Config.Multichar then self.license = 'license'..string.sub(identifier, 6) else self.license = 'license:'..identifier end + if Config.Multichar then self.license = 'license'.. identifier:sub(identifier:find(':'), identifier:len()) else self.license = 'license:'..identifier end ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.license, self.group)) diff --git a/[esx]/es_extended/server/commands.lua b/[esx]/es_extended/server/commands.lua index cdc668aa..0e2171d1 100644 --- a/[esx]/es_extended/server/commands.lua +++ b/[esx]/es_extended/server/commands.lua @@ -134,13 +134,13 @@ end, true, {help = _U('command_setgroup'), validate = true, arguments = { }}) ESX.RegisterCommand('save', 'admin', function(xPlayer, args, showError) - ESX.SavePlayer(args.playerId) + Core.SavePlayer(args.playerId) end, true, {help = _U('command_save'), validate = true, arguments = { {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} }}) ESX.RegisterCommand('saveall', 'admin', function(xPlayer, args, showError) - ESX.SavePlayers() + Core.SavePlayers() end, true, {help = _U('command_saveall')}) ESX.RegisterCommand('group', {"user", "admin"}, function(xPlayer, args, showError) diff --git a/[esx]/es_extended/server/common.lua b/[esx]/es_extended/server/common.lua index f6352ec4..c51429f6 100644 --- a/[esx]/es_extended/server/common.lua +++ b/[esx]/es_extended/server/common.lua @@ -1,34 +1,35 @@ ESX = {} ESX.Players = {} -ESX.UsableItemsCallbacks = {} -ESX.Items = {} -ESX.ServerCallbacks = {} -ESX.TimeoutCount = -1 -ESX.CancelledTimeouts = {} -ESX.Pickups = {} -ESX.PickupId = 0 ESX.Jobs = {} -ESX.RegisteredCommands = {} +ESX.Items = {} +Core = {} +Core.UsableItemsCallbacks = {} +Core.ServerCallbacks = {} +Core.TimeoutCount = -1 +Core.CancelledTimeouts = {} +Core.RegisteredCommands = {} +Core.Pickups = {} +Core.PickupId = 0 AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) end) -function getSharedObject() +exports('getSharedObject', function() return ESX -end +end) local function StartDBSync() Citizen.CreateThread(function() while true do Citizen.Wait(10 * 60 * 1000) - ESX.SavePlayers() + Core.SavePlayers() end end) end MySQL.ready(function() - MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) + MySQL.query('SELECT * FROM items', {}, function(result) for k,v in ipairs(result) do ESX.Items[v.name] = { label = v.label, @@ -40,13 +41,13 @@ MySQL.ready(function() end) local Jobs = {} - MySQL.Async.fetchAll('SELECT * FROM jobs', {}, function(jobs) + MySQL.query('SELECT * FROM jobs', {}, function(jobs) for k,v in ipairs(jobs) do Jobs[v.name] = v Jobs[v.name].grades = {} end - MySQL.Async.fetchAll('SELECT * FROM job_grades', {}, function(jobGrades) + MySQL.query('SELECT * FROM job_grades', {}, function(jobGrades) for k,v in ipairs(jobGrades) do if Jobs[v.job_name] then Jobs[v.job_name].grades[tostring(v.grade)] = v @@ -80,7 +81,7 @@ RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) local playerId = source - ESX.TriggerServerCallback(name, requestId, playerId, function(...) + Core.TriggerServerCallback(name, requestId, playerId, function(...) TriggerClientEvent('esx:serverCallback', playerId, requestId, ...) end, ...) end) diff --git a/[esx]/es_extended/server/functions.lua b/[esx]/es_extended/server/functions.lua index 1f5d41ee..3a32a92a 100644 --- a/[esx]/es_extended/server/functions.lua +++ b/[esx]/es_extended/server/functions.lua @@ -5,17 +5,17 @@ ESX.Trace = function(msg) end ESX.SetTimeout = function(msec, cb) - local id = ESX.TimeoutCount + 1 + local id = Core.TimeoutCount + 1 SetTimeout(msec, function() - if ESX.CancelledTimeouts[id] then - ESX.CancelledTimeouts[id] = nil + if Core.CancelledTimeouts[id] then + Core.CancelledTimeouts[id] = nil else cb() end end) - ESX.TimeoutCount = id + Core.TimeoutCount = id return id end @@ -29,10 +29,10 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) return end - if ESX.RegisteredCommands[name] then + if Core.RegisteredCommands[name] then print(('[^3WARNING^7] Command ^5"%s" already registered, overriding command'):format(name)) - if ESX.RegisteredCommands[name].suggestion then + if Core.RegisteredCommands[name].suggestion then TriggerClientEvent('chat:removeSuggestion', -1, ('/%s'):format(name)) end end @@ -44,10 +44,10 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) TriggerClientEvent('chat:addSuggestion', -1, ('/%s'):format(name), suggestion.help, suggestion.arguments) end - ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} + Core.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} RegisterCommand(name, function(playerId, args, rawCommand) - local command = ESX.RegisteredCommands[name] + local command = Core.RegisteredCommands[name] if not command.allowConsole and playerId == 0 then print(('[^3WARNING^7] ^5%s'):format(_U('commanderror_console'))) @@ -148,92 +148,62 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) end ESX.ClearTimeout = function(id) - ESX.CancelledTimeouts[id] = true + Core.CancelledTimeouts[id] = true end ESX.RegisterServerCallback = function(name, cb) - ESX.ServerCallbacks[name] = cb + Core.ServerCallbacks[name] = cb end -ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) - if ESX.ServerCallbacks[name] then - ESX.ServerCallbacks[name](source, cb, ...) +Core.TriggerServerCallback = function(name, requestId, source, cb, ...) + if Core.ServerCallbacks[name] then + Core.ServerCallbacks[name](source, cb, ...) else print(('[^3WARNING^7] Server callback ^5"%s"^0 does not exist. ^1Please Check The Server File for Errors!'):format(name)) end end -local savePlayers = -1 -Citizen.CreateThread(function() - savePlayers = MySQL.Sync.store("UPDATE users SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?") -end) - -ESX.SavePlayer = function(xPlayer, cb) - local asyncTasks = {} - - table.insert(asyncTasks, function(cb2) - MySQL.Async.execute(savePlayers, { - json.encode(xPlayer.getAccounts(true)), - xPlayer.job.name, - xPlayer.job.grade, - xPlayer.getGroup(), - json.encode(xPlayer.getCoords()), - json.encode(xPlayer.getInventory(true)), - json.encode(xPlayer.getLoadout(true)), - xPlayer.getIdentifier() - }, function(rowsChanged) - cb2() - end) - end) - - Async.parallel(asyncTasks, function(results) - print(('[^2INFO^7] Saved player ^5"%s^7"'):format(xPlayer.getName())) - - if cb then - cb() +Core.SavePlayer = function(xPlayer, cb) + MySQL.prepare('UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?', { + json.encode(xPlayer.getAccounts(true)), + xPlayer.job.name, + xPlayer.job.grade, + xPlayer.group, + json.encode(xPlayer.getCoords()), + json.encode(xPlayer.getInventory(true)), + json.encode(xPlayer.getLoadout(true)), + xPlayer.identifier + }, function(affectedRows) + if affectedRows == 1 then + print(('[^2INFO^7] Saved player ^5"%s^7"'):format(xPlayer.name)) end + if cb then cb() end end) end -ESX.SavePlayers = function(cb) +Core.SavePlayers = function(cb) local xPlayers = ESX.GetExtendedPlayers() - if #xPlayers > 0 then + local count = #xPlayers + if count > 0 then + local parameters = {} local time = os.time() - - local selectListWithNames = "SELECT '%s' AS identifier, '%s' AS new_accounts, '%s' AS new_job, %s AS new_job_grade, '%s' AS new_group, '%s' AS new_loadout, '%s' AS new_position, '%s' AS new_inventory " - local selectListNoNames = "SELECT '%s', '%s', '%s' , %s, '%s', '%s', '%s', '%s' " - - local updateCommand = 'UPDATE users u JOIN (' - - local selectList = selectListNoNames - local first = true - for k, xPlayer in pairs(xPlayers) do - if first == false then - updateCommand = updateCommand .. ' UNION ' - else - selectList = selectListWithNames - end - - updateCommand = updateCommand .. string.format(selectList, - xPlayer.identifier, + for i=1, count do + local xPlayer = xPlayers[i] + parameters[#parameters+1] = { json.encode(xPlayer.getAccounts(true)), xPlayer.job.name, xPlayer.job.grade, - xPlayer.getGroup(), - json.encode(xPlayer.getLoadout(true)), + xPlayer.group, json.encode(xPlayer.getCoords()), - json.encode(xPlayer.getInventory(true)) - ) - - first = false + json.encode(xPlayer.getInventory(true)), + json.encode(xPlayer.getLoadout(true)), + xPlayer.identifier + } end - - updateCommand = updateCommand .. ' ) vals ON u.identifier = vals.identifier SET accounts = new_accounts, job = new_job, job_grade = new_job_grade, `group` = new_group, loadout = new_loadout, `position` = new_position, inventory = new_inventory' - - MySQL.Async.fetchAll(updateCommand, {}, - function(result) - if result then - if cb then cb() else print(('[^2INFO^7] Saved %s of %s player(s) over %s seconds'):format(result.affectedRows, #xPlayers, os.time() - time)) end + MySQL.prepare("UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?", parameters, + function(results) + if results then + if type(cb) == 'function' then cb() else print(('[^2INFO^7] Saved %s %s over %s ms'):format(count, count > 1 and 'players' or 'player', (os.time() - time) / 1000000)) end end end) end @@ -285,11 +255,11 @@ ESX.GetIdentifier = function(playerId) end ESX.RegisterUsableItem = function(item, cb) - ESX.UsableItemsCallbacks[item] = cb + Core.UsableItemsCallbacks[item] = cb end ESX.UseItem = function(source, item) - ESX.UsableItemsCallbacks[item](source, item) + Core.UsableItemsCallbacks[item](source, item) end ESX.GetItemLabel = function(item) @@ -298,24 +268,36 @@ ESX.GetItemLabel = function(item) end end +ESX.GetJobs = function() + return ESX.Jobs +end + +ESX.GetUsableItems = function() + local Usables = {} + for k in pairs(Core.UsableItemsCallbacks) do + Usables[k] = true + end + return Usables +end + ESX.CreatePickup = function(type, name, count, label, playerId, components, tintIndex) - local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + local pickupId = (Core.PickupId == 65635 and 0 or Core.PickupId + 1) local xPlayer = ESX.GetPlayerFromId(playerId) local coords = xPlayer.getCoords() - ESX.Pickups[pickupId] = { + Core.Pickups[pickupId] = { type = type, name = name, count = count, label = label, coords = coords } if type == 'item_weapon' then - ESX.Pickups[pickupId].components = components - ESX.Pickups[pickupId].tintIndex = tintIndex + Core.Pickups[pickupId].components = components + Core.Pickups[pickupId].tintIndex = tintIndex end TriggerClientEvent('esx:createPickup', -1, pickupId, label, coords, type, name, components, tintIndex) - ESX.PickupId = pickupId + Core.PickupId = pickupId end ESX.DoesJobExist = function(job, grade) @@ -329,3 +311,18 @@ ESX.DoesJobExist = function(job, grade) return false end + +Core.IsPlayerAdmin = function(playerId) + if (IsPlayerAceAllowed(playerId, 'command') or GetConvar('sv_lan', '') == 'true') and true or false then + return true + end + + local xPlayer = ESX.GetPlayerFromId(playerId) + if xPlayer then + if xPlayer.group == 'admin' or xPlayer.group == 'superadmin' then + return true + end + end + + return false +end diff --git a/[esx]/es_extended/server/main.lua b/[esx]/es_extended/server/main.lua index bb5bfcd8..2c55d9cf 100644 --- a/[esx]/es_extended/server/main.lua +++ b/[esx]/es_extended/server/main.lua @@ -1,27 +1,18 @@ -local NewPlayer, LoadPlayer = -1, -1 -Citizen.CreateThread(function() - SetMapName('San Andreas') - SetGameType('ESX Legacy') +SetMapName('San Andreas') +SetGameType('ESX Legacy') - local query = '`accounts`, `job`, `job_grade`, `group`, `position`, `inventory`, `skin`, `loadout`' -- Select these fields from the database - if Config.Multichar or Config.Identity then -- append these fields to the select query - query = query..', `firstname`, `lastname`, `dateofbirth`, `sex`, `height`' - end +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 -- insert identity data with creation - MySQL.Async.store("INSERT INTO `users` SET `accounts` = ?, `identifier` = ?, `group` = ?, `firstname` = ?, `lastname` = ?, `dateofbirth` = ?, `sex` = ?, `height` = ?", function(storeId) - NewPlayer = storeId - end) - else - MySQL.Async.store("INSERT INTO `users` SET `accounts` = ?, `identifier` = ?, `group` = ?", function(storeId) - NewPlayer = storeId - end) - end +if Config.Multichar then + newPlayer = newPlayer..', `firstname` = ?, `lastname` = ?, `dateofbirth` = ?, `sex` = ?, `height` = ?"' +end - MySQL.Async.store("SELECT "..query.." FROM `users` WHERE identifier = ?", function(storeId) - LoadPlayer = storeId - end) -end) +if Config.Multichar or Config.Identity then + loadPlayer = loadPlayer..', `firstname`, `lastname`, `dateofbirth`, `sex`, `height`' +end + +loadPlayer = loadPlayer..' FROM `users` WHERE identifier = ?' if Config.Multichar then AddEventHandler('esx:onPlayerJoined', function(src, char, data) @@ -49,13 +40,12 @@ function onPlayerJoined(playerId) 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 - MySQL.Async.fetchScalar('SELECT 1 FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result then - loadESXPlayer(identifier, playerId, false) - else createESXPlayer(identifier, playerId) end - end) + 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.') @@ -69,7 +59,7 @@ function createESXPlayer(identifier, playerId, data) accounts[account] = money end - if IsPlayerAceAllowed(playerId, "command") then + 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 @@ -77,49 +67,44 @@ function createESXPlayer(identifier, playerId, data) end if not Config.Multichar then - MySQL.Async.execute(NewPlayer, { - json.encode(accounts), - identifier, - defaultGroup, - }, function(rowsChanged) + MySQL.prepare(newPlayer, { json.encode(accounts), identifier, defaultGroup }, function() loadESXPlayer(identifier, playerId, true) end) else - MySQL.Async.execute(NewPlayer, { - json.encode(accounts), - identifier, - defaultGroup, - data.firstname, - data.lastname, - data.dateofbirth, - data.sex, - data.height, - }, function(rowsChanged) + 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 -AddEventHandler('playerConnecting', function(name, setCallback, deferrals) - deferrals.defer() - local playerId = source - local identifier = ESX.GetIdentifier(playerId) - Citizen.Wait(100) +if not Config.Multichar then + 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)) + 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() + 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 - 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) +end function loadESXPlayer(identifier, playerId, isNew) - local tasks = {} - local userData = { accounts = {}, inventory = {}, @@ -129,179 +114,171 @@ function loadESXPlayer(identifier, playerId, isNew) weight = 0 } - table.insert(tasks, function(cb) - MySQL.Async.fetchAll(LoadPlayer, { identifier - }, function(result) - local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].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[1].accounts and result[1].accounts ~= '' then - local accounts = json.decode(result[1].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,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 - - 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.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 - - -- Inventory - if result[1].inventory and result[1].inventory ~= '' then - local inventory = json.decode(result[1].inventory) - - 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 - - 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 = ESX.UsableItemsCallbacks[name] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - end - - table.sort(userData.inventory, function(a, b) - return a.label < b.label - end) - - -- Group - if result[1].group then - if result[1].group == "superadmin" then - userData.group = "admin" - else - userData.group = result[1].group - end - else - userData.group = 'user' - end - - -- Loadout - if result[1].loadout and result[1].loadout ~= '' then - local loadout = json.decode(result[1].loadout) - - 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 - - table.insert(userData.loadout, { - name = name, - ammo = weapon.ammo, - label = label, - components = weapon.components, - tintIndex = weapon.tintIndex - }) - end - end - end - - -- Position - if result[1].position and result[1].position ~= '' then - userData.coords = json.decode(result[1].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[1].skin and result[1].skin ~= '' then - userData.skin = json.decode(result[1].skin) - else - if userData.sex == 'f' then userData.skin = {sex=1} else userData.skin = {sex=0} end - end - - -- Identity - if result[1].firstname and result[1].firstname ~= '' then - userData.firstname = result[1].firstname - userData.lastname = result[1].lastname - userData.playerName = userData.firstname..' '..userData.lastname - if result[1].dateofbirth then userData.dateofbirth = result[1].dateofbirth end - if result[1].sex then userData.sex = result[1].sex end - if result[1].height then userData.height = result[1].height end - end - - cb() - end) - end) - - Async.parallel(tasks, function(results) - 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 + for account,money in pairs(accounts) do + foundAccounts[account] = money end + end - TriggerEvent('esx:playerLoaded', playerId, xPlayer, isNew) + 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 - 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) + -- 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 - xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) - xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) - print(('[^2INFO^0] Player ^5"%s" ^0has connected to the server. ID: ^5%s^7'):format(xPlayer.getName(), playerId)) + 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.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 + + -- Inventory + 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] + + 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 + + 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) + + -- 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 result.loadout and result.loadout ~= '' then + local loadout = json.decode(result.loadout) + + 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 + + table.insert(userData.loadout, { + name = name, + ammo = weapon.ammo, + label = label, + components = weapon.components, + tintIndex = weapon.tintIndex + }) + 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 + + -- 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 + + 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 + + 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:createMissingPickups', Core.Pickups) + 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) @@ -319,7 +296,7 @@ AddEventHandler('playerDropped', function(reason) if xPlayer then TriggerEvent('esx:playerDropped', playerId, reason) - ESX.SavePlayer(xPlayer, function() + Core.SavePlayer(xPlayer, function() ESX.Players[playerId] = nil end) end @@ -331,7 +308,7 @@ if Config.Multichar then if xPlayer then TriggerEvent('esx:playerDropped', playerId, reason) - ESX.SavePlayer(xPlayer, function() + Core.SavePlayer(xPlayer, function() ESX.Players[playerId] = nil end) end @@ -512,7 +489,7 @@ end) RegisterNetEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(pickupId) - local pickup, xPlayer, success = ESX.Pickups[pickupId], ESX.GetPlayerFromId(source) + local pickup, xPlayer, success = Core.Pickups[pickupId], ESX.GetPlayerFromId(source) if pickup then if pickup.type == 'item_standard' then @@ -540,7 +517,7 @@ AddEventHandler('esx:onPickup', function(pickupId) end if success then - ESX.Pickups[pickupId] = nil + Core.Pickups[pickupId] = nil TriggerClientEvent('esx:removePickup', -1, pickupId) end end @@ -592,7 +569,7 @@ AddEventHandler('txAdmin:events:scheduledRestart', function(eventData) if eventData.secondsRemaining == 60 then Citizen.CreateThread(function() Citizen.Wait(50000) - ESX.SavePlayers() + Core.SavePlayers() end) end end) diff --git a/[esx]/esx_identity/server/main.lua b/[esx]/esx_identity/server/main.lua index 88223d0d..c3612bbd 100644 --- a/[esx]/esx_identity/server/main.lua +++ b/[esx]/esx_identity/server/main.lua @@ -9,17 +9,16 @@ if Config.UseDeferrals then Citizen.Wait(100) if identifier then - MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result[1] then - if result[1].firstname then + MySQL.single('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = ?', {identifier}, + function(result) + if result then + if result.firstname then playerIdentity[identifier] = { - firstName = result[1].firstname, - lastName = result[1].lastname, - dateOfBirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height + firstName = result.firstname, + lastName = result.lastname, + dateOfBirth = result.dateofbirth, + sex = result.sex, + height = result.height } deferrals.done() @@ -107,17 +106,16 @@ elseif not Config.UseDeferrals then Citizen.Wait(40) if identifier then - MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result[1] then - if result[1].firstname then + MySQL.single('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = ?', {identifier}, + function(result) + if result then + if result.firstname then playerIdentity[identifier] = { - firstName = result[1].firstname, - lastName = result[1].lastname, - dateOfBirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height + firstName = result.firstname, + lastName = result.lastname, + dateOfBirth = result.dateofbirth, + sex = result.sex, + height = result.height } alreadyRegistered[identifier] = true @@ -225,17 +223,16 @@ elseif not Config.UseDeferrals then end) function checkIdentity(xPlayer) - MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) - if result[1] then - if result[1].firstname then + MySQL.single('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = ?', {identifier}, + function(result) + if result then + if result.firstname then playerIdentity[xPlayer.identifier] = { - firstName = result[1].firstname, - lastName = result[1].lastname, - dateOfBirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height + firstName = result.firstname, + lastName = result.lastname, + dateOfBirth = result.dateofbirth, + sex = result.sex, + height = result.height } alreadyRegistered[xPlayer.identifier] = true @@ -284,7 +281,7 @@ if Config.EnableCommands then ESX.RegisterCommand('chardel', 'user', function(xPlayer, args, showError) if xPlayer and xPlayer.getName() then if Config.UseDeferrals then - xPlayer.kick(_('deleted_identity')) + xPlayer.kick(_U('deleted_identity')) Citizen.Wait(1500) deleteIdentity(xPlayer) xPlayer.showNotification(_U('deleted_character')) @@ -367,61 +364,16 @@ function deleteIdentity(xPlayer) end function saveIdentityToDatabase(identifier, identity) - MySQL.Sync.execute('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', { - ['@identifier'] = identifier, - ['@firstname'] = identity.firstName, - ['@lastname'] = identity.lastName, - ['@dateofbirth'] = identity.dateOfBirth, - ['@sex'] = identity.sex, - ['@height'] = identity.height - }) + MySQL.update.await('UPDATE users SET firstname = ?, lastname = ?, dateofbirth = ?, sex = ?, height = ? WHERE identifier = ?', {identity.firstName, identity.lastName, identity.dateOfBirth, identity.sex, identity.height. identifier}) end function deleteIdentityFromDatabase(xPlayer) - MySQL.Sync.execute('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height , skin = @skin WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier, - ['@firstname'] = NULL, - ['@lastname'] = NULL, - ['@dateofbirth'] = NULL, - ['@sex'] = NULL, - ['@height'] = NULL, - ['@skin'] = NULL - }) + MySQL.query.await('UPDATE users SET firstname = ?, lastname = ?, dateofbirth = ?, sex = ?, height = ?, skin = ? WHERE identifier = ?', {nil, nil, nil, nil, nil, xPlayer.identifier}) if Config.FullCharDelete then - MySQL.Sync.execute('UPDATE addon_account_data SET money = 0 WHERE account_name = @account_name AND owner = @owner', { - ['@account_name'] = 'bank_savings', - ['@owner'] = xPlayer.identifier - }) + MySQL.update.await('UPDATE addon_account_data SET money = 0 WHERE account_name IN (?) AND owner = ?', {{'bank_savings', 'caution'}, xPlayer.identifier}) - MySQL.Sync.execute('UPDATE addon_account_data SET money = 0 WHERE account_name = @account_name AND owner = @owner', { - ['@account_name'] = 'caution', - ['@owner'] = xPlayer.identifier - }) - - MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_ears', - ['@owner'] = xPlayer.identifier - }) - - MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_glasses', - ['@owner'] = xPlayer.identifier - }) - - MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_helmet', - ['@owner'] = xPlayer.identifier - }) - - MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_mask', - ['@owner'] = xPlayer.identifier - }) + MySQL.prepare.await('UPDATE datastore_data SET data = ? WHERE name IN (?) AND owner = ?', {'\'{}\'', {'user_ears', 'user_glasses', 'user_helmet', 'user_mask'}, xPlayer.identifier}) end end diff --git a/[esx]/esx_menu_default/client/main.lua b/[esx]/esx_menu_default/client/main.lua index 54a6d428..2873f490 100644 --- a/[esx]/esx_menu_default/client/main.lua +++ b/[esx]/esx_menu_default/client/main.lua @@ -1,97 +1,95 @@ -Citizen.CreateThread(function() - local ESX = exports['es_extended']:getSharedObject() - local GUI, MenuType = {}, 'default' - GUI.Time = 0 +local ESX = exports.es_extended:getSharedObject() +local GUI, MenuType = {}, 'default' +GUI.Time = 0 - local openMenu = function(namespace, name, data) - SendNUIMessage({ - action = 'openMenu', - namespace = namespace, - name = name, - data = data - }) +local openMenu = function(namespace, name, data) + SendNUIMessage({ + action = 'openMenu', + namespace = namespace, + name = name, + data = data + }) +end + +local closeMenu = function(namespace, name) + SendNUIMessage({ + action = 'closeMenu', + namespace = namespace, + name = name, + data = data + }) +end + +ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu) + +RegisterNUICallback('menu_submit', function(data, cb) + local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + if menu.submit ~= nil then + menu.submit(data, menu) + end + cb('OK') +end) + +RegisterNUICallback('menu_cancel', function(data, cb) + local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + + if menu.cancel ~= nil then + menu.cancel(data, menu) + end + cb('OK') +end) + +RegisterNUICallback('menu_change', function(data, cb) + local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + + for i=1, #data.elements, 1 do + menu.setElement(i, 'value', data.elements[i].value) + + if data.elements[i].selected then + menu.setElement(i, 'selected', true) + else + menu.setElement(i, 'selected', false) + end + end + + if menu.change ~= nil then + menu.change(data, menu) + end + cb('OK') +end) + +Citizen.CreateThread(function() + while true do + Citizen.Wait(15) + + if IsControlPressed(0, 18) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + SendNUIMessage({action = 'controlPressed', control = 'ENTER'}) + GUI.Time = GetGameTimer() + end + + if IsControlPressed(0, 177) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + SendNUIMessage({action = 'controlPressed', control = 'BACKSPACE'}) + GUI.Time = GetGameTimer() + end + + if IsControlPressed(0, 27) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then + SendNUIMessage({action = 'controlPressed', control = 'TOP'}) + GUI.Time = GetGameTimer() + end + + if IsControlPressed(0, 173) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then + SendNUIMessage({action = 'controlPressed', control = 'DOWN'}) + GUI.Time = GetGameTimer() + end + + if IsControlPressed(0, 174) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + SendNUIMessage({action = 'controlPressed', control = 'LEFT'}) + GUI.Time = GetGameTimer() + end + + if IsControlPressed(0, 175) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + SendNUIMessage({action = 'controlPressed', control = 'RIGHT'}) + GUI.Time = GetGameTimer() + end end - - local closeMenu = function(namespace, name) - SendNUIMessage({ - action = 'closeMenu', - namespace = namespace, - name = name, - data = data - }) - end - - ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu) - - RegisterNUICallback('menu_submit', function(data, cb) - local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - if menu.submit ~= nil then - menu.submit(data, menu) - end - cb('OK') - end) - - RegisterNUICallback('menu_cancel', function(data, cb) - local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - - if menu.cancel ~= nil then - menu.cancel(data, menu) - end - cb('OK') - end) - - RegisterNUICallback('menu_change', function(data, cb) - local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - - for i=1, #data.elements, 1 do - menu.setElement(i, 'value', data.elements[i].value) - - if data.elements[i].selected then - menu.setElement(i, 'selected', true) - else - menu.setElement(i, 'selected', false) - end - end - - if menu.change ~= nil then - menu.change(data, menu) - end - cb('OK') - end) - - Citizen.CreateThread(function() - while true do - Citizen.Wait(15) - - if IsControlPressed(0, 18) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then - SendNUIMessage({action = 'controlPressed', control = 'ENTER'}) - GUI.Time = GetGameTimer() - end - - if IsControlPressed(0, 177) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then - SendNUIMessage({action = 'controlPressed', control = 'BACKSPACE'}) - GUI.Time = GetGameTimer() - end - - if IsControlPressed(0, 27) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then - SendNUIMessage({action = 'controlPressed', control = 'TOP'}) - GUI.Time = GetGameTimer() - end - - if IsControlPressed(0, 173) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then - SendNUIMessage({action = 'controlPressed', control = 'DOWN'}) - GUI.Time = GetGameTimer() - end - - if IsControlPressed(0, 174) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then - SendNUIMessage({action = 'controlPressed', control = 'LEFT'}) - GUI.Time = GetGameTimer() - end - - if IsControlPressed(0, 175) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then - SendNUIMessage({action = 'controlPressed', control = 'RIGHT'}) - GUI.Time = GetGameTimer() - end - end - end) end) diff --git a/[esx]/esx_menu_dialog/client/main.lua b/[esx]/esx_menu_dialog/client/main.lua index 8afb263f..b7662af3 100644 --- a/[esx]/esx_menu_dialog/client/main.lua +++ b/[esx]/esx_menu_dialog/client/main.lua @@ -1,105 +1,103 @@ +local ESX = exports.es_extended:getSharedObject() +local Timeouts, OpenedMenus, MenuType = {}, {}, 'dialog' + +local openMenu = function(namespace, name, data) + for i=1, #Timeouts, 1 do + ESX.ClearTimeout(Timeouts[i]) + end + + OpenedMenus[namespace .. '_' .. name] = true + + SendNUIMessage({ + action = 'openMenu', + namespace = namespace, + name = name, + data = data + }) + + local timeoutId = ESX.SetTimeout(200, function() + SetNuiFocus(true, true) + end) + + table.insert(Timeouts, timeoutId) +end + +local closeMenu = function(namespace, name) + OpenedMenus[namespace .. '_' .. name] = nil + + SendNUIMessage({ + action = 'closeMenu', + namespace = namespace, + name = name, + data = data + }) + + if ESX.Table.SizeOf(OpenedMenus) == 0 then + SetNuiFocus(false) + end + +end + +ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu) + +AddEventHandler('esx_menu_dialog:message:menu_submit', function(data) + local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + local cancel = false + + if menu.submit then + -- is the submitted data a number? + if tonumber(data.value) then + data.value = ESX.Math.Round(tonumber(data.value)) + + -- check for negative value + if tonumber(data.value) <= 0 then + cancel = true + end + end + + data.value = ESX.Math.Trim(data.value) + + -- don't submit if the value is negative or if it's 0 + if cancel then + ESX.ShowNotification('That input is not allowed!') + else + menu.submit(data, menu) + end + end +end) + +AddEventHandler('esx_menu_dialog:message:menu_cancel', function(data) + local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + + if menu.cancel ~= nil then + menu.cancel(data, menu) + end +end) + +AddEventHandler('esx_menu_dialog:message:menu_change', function(data) + local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + + if menu.change ~= nil then + menu.change(data, menu) + end +end) + Citizen.CreateThread(function() - local ESX = exports['es_extended']:getSharedObject() - local Timeouts, OpenedMenus, MenuType = {}, {}, 'dialog' + while true do + Citizen.Wait(10) - local openMenu = function(namespace, name, data) - for i=1, #Timeouts, 1 do - ESX.ClearTimeout(Timeouts[i]) + if ESX.Table.SizeOf(OpenedMenus) > 0 then + DisableControlAction(0, 1, true) -- LookLeftRight + DisableControlAction(0, 2, true) -- LookUpDown + DisableControlAction(0, 142, true) -- MeleeAttackAlternate + DisableControlAction(0, 106, true) -- VehicleMouseControlOverride + DisableControlAction(0, 12, true) -- WeaponWheelUpDown + DisableControlAction(0, 14, true) -- WeaponWheelNext + DisableControlAction(0, 15, true) -- WeaponWheelPrev + DisableControlAction(0, 16, true) -- SelectNextWeapon + DisableControlAction(0, 17, true) -- SelectPrevWeapon + else + Citizen.Wait(500) end - - OpenedMenus[namespace .. '_' .. name] = true - - SendNUIMessage({ - action = 'openMenu', - namespace = namespace, - name = name, - data = data - }) - - local timeoutId = ESX.SetTimeout(200, function() - SetNuiFocus(true, true) - end) - - table.insert(Timeouts, timeoutId) end - - local closeMenu = function(namespace, name) - OpenedMenus[namespace .. '_' .. name] = nil - - SendNUIMessage({ - action = 'closeMenu', - namespace = namespace, - name = name, - data = data - }) - - if ESX.Table.SizeOf(OpenedMenus) == 0 then - SetNuiFocus(false) - end - - end - - ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu) - - AddEventHandler('esx_menu_dialog:message:menu_submit', function(data) - local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - local cancel = false - - if menu.submit then - -- is the submitted data a number? - if tonumber(data.value) then - data.value = ESX.Math.Round(tonumber(data.value)) - - -- check for negative value - if tonumber(data.value) <= 0 then - cancel = true - end - end - - data.value = ESX.Math.Trim(data.value) - - -- don't submit if the value is negative or if it's 0 - if cancel then - ESX.ShowNotification('That input is not allowed!') - else - menu.submit(data, menu) - end - end - end) - - AddEventHandler('esx_menu_dialog:message:menu_cancel', function(data) - local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - - if menu.cancel ~= nil then - menu.cancel(data, menu) - end - end) - - AddEventHandler('esx_menu_dialog:message:menu_change', function(data) - local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - - if menu.change ~= nil then - menu.change(data, menu) - end - end) - - Citizen.CreateThread(function() - while true do - Citizen.Wait(10) - - if ESX.Table.SizeOf(OpenedMenus) > 0 then - DisableControlAction(0, 1, true) -- LookLeftRight - DisableControlAction(0, 2, true) -- LookUpDown - DisableControlAction(0, 142, true) -- MeleeAttackAlternate - DisableControlAction(0, 106, true) -- VehicleMouseControlOverride - DisableControlAction(0, 12, true) -- WeaponWheelUpDown - DisableControlAction(0, 14, true) -- WeaponWheelNext - DisableControlAction(0, 15, true) -- WeaponWheelPrev - DisableControlAction(0, 16, true) -- SelectNextWeapon - DisableControlAction(0, 17, true) -- SelectPrevWeapon - else - Citizen.Wait(500) - end - end - end) end) \ No newline at end of file diff --git a/[esx]/esx_skin/server/main.lua b/[esx]/esx_skin/server/main.lua index 01dbba3e..18460ca2 100644 --- a/[esx]/esx_skin/server/main.lua +++ b/[esx]/esx_skin/server/main.lua @@ -10,7 +10,7 @@ AddEventHandler('esx_skin:save', function(skin) xPlayer.setMaxWeight(defaultMaxWeight) end - MySQL.Async.execute('UPDATE users SET skin = @skin WHERE identifier = @identifier', { + MySQL.update('UPDATE users SET skin = @skin WHERE identifier = @identifier', { ['@skin'] = json.encode(skin), ['@identifier'] = xPlayer.identifier }) @@ -34,7 +34,7 @@ end) ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT skin FROM users WHERE identifier = @identifier', { + MySQL.query('SELECT skin FROM users WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }, function(users) local user, skin = users[1] diff --git a/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua b/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua index 7f082cd4..df099306 100644 --- a/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua +++ b/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua @@ -8,37 +8,25 @@ function CreateAddonAccount(name, owner, money) self.addMoney = function(m) self.money = self.money + m self.save() - - TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end self.removeMoney = function(m) self.money = self.money - m self.save() - - TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end self.setMoney = function(m) self.money = m self.save() - - TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end self.save = function() if self.owner == nil then - MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name', { - ['@account_name'] = self.name, - ['@money'] = self.money - }) + MySQL.update('UPDATE addon_account_data SET money = ? WHERE account_name = ?', {self.money, self.name}) else - MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name AND owner = @owner', { - ['@account_name'] = self.name, - ['@money'] = self.money, - ['@owner'] = self.owner - }) + MySQL.update('UPDATE addon_account_data SET money = ? WHERE account_name = ? AND owner = ?', {self.money, self.name, self.owner}) end + TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end return self diff --git a/[esx_addons]/esx_addonaccount/server/main.lua b/[esx_addons]/esx_addonaccount/server/main.lua index 26172ea4..39a580fe 100644 --- a/[esx_addons]/esx_addonaccount/server/main.lua +++ b/[esx_addons]/esx_addonaccount/server/main.lua @@ -1,41 +1,33 @@ local AccountsIndex, Accounts, SharedAccounts = {}, {}, {} -MySQL.ready(function() - local result = MySQL.Sync.fetchAll('SELECT * FROM addon_account') +AddEventHandler('onResourceStart', function(resourceName) + if resourceName == GetCurrentResourceName() then + local accounts = MySQL.query.await('SELECT * FROM addon_account LEFT JOIN addon_account_data ON addon_account.name = addon_account_data.account_name UNION SELECT * FROM addon_account RIGHT JOIN addon_account_data ON addon_account.name = addon_account_data.account_name') - for i=1, #result, 1 do - local name = result[i].name - local label = result[i].label - local shared = result[i].shared - - local result2 = MySQL.Sync.fetchAll('SELECT * FROM addon_account_data WHERE account_name = @account_name', { - ['@account_name'] = name - }) - - if shared == 0 then - table.insert(AccountsIndex, name) - Accounts[name] = {} - - for j=1, #result2, 1 do - local addonAccount = CreateAddonAccount(name, result2[j].owner, result2[j].money) - table.insert(Accounts[name], addonAccount) - end - else - local money = nil - - if #result2 == 0 then - MySQL.Sync.execute('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, NULL)', { - ['@account_name'] = name, - ['@money'] = 0 - }) - - money = 0 + local newAccounts = {} + for i = 1, #accounts do + local account = accounts[i] + if account.shared == 0 then + if not Accounts[account.name] then + AccountsIndex[#AccountsIndex + 1] = account.name + Accounts[account.name] = {} + end + Accounts[account.name][#Accounts[account.name] + 1] = CreateAddonAccount(account.name, account.owner, account.money) else - money = result2[1].money + if account.money then + SharedAccounts[account.name] = CreateAddonAccount(account.name, nil, account.money) + else + newAccounts[#newAccounts + 1] = {account.name, 0} + end end + end - local addonAccount = CreateAddonAccount(name, nil, money) - SharedAccounts[name] = addonAccount + if next(newAccounts) then + MySQL.prepare('INSERT INTO addon_account_data (account_name, money) VALUES (?, ?)', newAccounts) + for i = 1, #newAccounts do + local newAccount = newAccounts[i] + SharedAccounts[newAccount[1]] = CreateAddonAccount(newAccount[1], nil, 0) + end end end end) @@ -68,17 +60,13 @@ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local account = GetAccount(name, xPlayer.identifier) if account == nil then - MySQL.Async.execute('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, @owner)', { - ['@account_name'] = name, - ['@money'] = 0, - ['@owner'] = xPlayer.identifier - }) + MySQL.insert('INSERT INTO addon_account_data (account_name, money, owner) VALUES (?, ?, ?)', {name, 0, xPlayer.identifier}) account = CreateAddonAccount(name, xPlayer.identifier, 0) - table.insert(Accounts[name], account) + Accounts[name][#Accounts[name] + 1] = account end - table.insert(addonAccounts, account) + addonAccounts[#addonAccounts + 1] = account end xPlayer.set('addonAccounts', addonAccounts) diff --git a/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua b/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua index e4f02a2c..5955ca72 100644 --- a/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua +++ b/[esx_addons]/esx_addoninventory/server/classes/addoninventory.lua @@ -42,14 +42,14 @@ function CreateAddonInventory(name, owner, items) table.insert(self.items, item) if self.owner == nil then - MySQL.Async.execute('INSERT INTO addon_inventory_items (inventory_name, name, count) VALUES (@inventory_name, @item_name, @count)', + MySQL.update('INSERT INTO addon_inventory_items (inventory_name, name, count) VALUES (@inventory_name, @item_name, @count)', { ['@inventory_name'] = self.name, ['@item_name'] = name, ['@count'] = 0 }) else - MySQL.Async.execute('INSERT INTO addon_inventory_items (inventory_name, name, count, owner) VALUES (@inventory_name, @item_name, @count, @owner)', + MySQL.update('INSERT INTO addon_inventory_items (inventory_name, name, count, owner) VALUES (@inventory_name, @item_name, @count, @owner)', { ['@inventory_name'] = self.name, ['@item_name'] = name, @@ -63,13 +63,13 @@ function CreateAddonInventory(name, owner, items) self.saveItem = function(name, count) if self.owner == nil then - MySQL.Async.execute('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name', { + MySQL.update('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name', { ['@inventory_name'] = self.name, ['@item_name'] = name, ['@count'] = count }) else - MySQL.Async.execute('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name AND owner = @owner', { + MySQL.update('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name AND owner = @owner', { ['@inventory_name'] = self.name, ['@item_name'] = name, ['@count'] = count, diff --git a/[esx_addons]/esx_addoninventory/server/main.lua b/[esx_addons]/esx_addoninventory/server/main.lua index e9193177..509da8a3 100644 --- a/[esx_addons]/esx_addoninventory/server/main.lua +++ b/[esx_addons]/esx_addoninventory/server/main.lua @@ -2,20 +2,20 @@ Items = {} local InventoriesIndex, Inventories, SharedInventories = {}, {}, {} MySQL.ready(function() - local items = MySQL.Sync.fetchAll('SELECT * FROM items') + local items = MySQL.query.await('SELECT * FROM items') for i=1, #items, 1 do Items[items[i].name] = items[i].label end - local result = MySQL.Sync.fetchAll('SELECT * FROM addon_inventory') + local result = MySQL.query.await('SELECT * FROM addon_inventory') for i=1, #result, 1 do local name = result[i].name local label = result[i].label local shared = result[i].shared - local result2 = MySQL.Sync.fetchAll('SELECT * FROM addon_inventory_items WHERE inventory_name = @inventory_name', { + local result2 = MySQL.query.await('SELECT * FROM addon_inventory_items WHERE inventory_name = @inventory_name', { ['@inventory_name'] = name }) diff --git a/[esx_addons]/esx_ambulancejob/client/vehicle.lua b/[esx_addons]/esx_ambulancejob/client/vehicle.lua index a14a6b33..0b2013ed 100644 --- a/[esx_addons]/esx_ambulancejob/client/vehicle.lua +++ b/[esx_addons]/esx_ambulancejob/client/vehicle.lua @@ -109,17 +109,17 @@ function OpenVehicleSpawnerMenu(type, hospital, part, partNum) end function StoreNearbyVehicle(playerCoords) - local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} - - if #vehicles > 0 then - for k,v in ipairs(vehicles) do + local vehicles, plates, index = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {}, {} + if next(vehicles) then + for i = 1, #vehicles do + local vehicle = vehicles[i] + -- Make sure the vehicle we're saving is empty, or else it wont be deleted - if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then - table.insert(vehiclePlates, { - vehicle = v, - plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) - }) + if GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) then + local plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) + plates[#plates + 1] = plate + index[plate] = vehicle end end else @@ -127,11 +127,11 @@ function StoreNearbyVehicle(playerCoords) return end - ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(storeSuccess, foundNum) - if storeSuccess then - local vehicleId = vehiclePlates[foundNum] + ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(plate) + if plate then + local vehicleId = index[plate] local attempts = 0 - ESX.Game.DeleteVehicle(vehicleId.vehicle) + ESX.Game.DeleteVehicle(vehicleId) isBusy = true Citizen.CreateThread(function() @@ -142,7 +142,7 @@ function StoreNearbyVehicle(playerCoords) end) -- Workaround for vehicle not deleting when other players are near it. - while DoesEntityExist(vehicleId.vehicle) do + while DoesEntityExist(vehicleId) do Citizen.Wait(500) attempts = attempts + 1 @@ -153,9 +153,10 @@ function StoreNearbyVehicle(playerCoords) vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0) if #vehicles > 0 then - for k,v in ipairs(vehicles) do - if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then - ESX.Game.DeleteVehicle(v) + for i = 1, #vehicles do + local vehicle = vehicles[i] + if ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) == plate then + ESX.Game.DeleteVehicle(vehicle) break end end @@ -167,7 +168,7 @@ function StoreNearbyVehicle(playerCoords) else ESX.ShowNotification(_U('garage_has_notstored')) end - end, vehiclePlates) + end, plates) end function GetAvailableVehicleSpawnPoint(hospital, part, partNum) diff --git a/[esx_addons]/esx_ambulancejob/server/main.lua b/[esx_addons]/esx_ambulancejob/server/main.lua index ee7a5b7c..e7dc4486 100644 --- a/[esx_addons]/esx_ambulancejob/server/main.lua +++ b/[esx_addons]/esx_ambulancejob/server/main.lua @@ -178,14 +178,8 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb if xPlayer.getMoney() >= price then xPlayer.removeMoney(price) - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (@owner, @vehicle, @plate, @type, @job, @stored)', { - ['@owner'] = xPlayer.identifier, - ['@vehicle'] = json.encode(vehicleProps), - ['@plate'] = vehicleProps.plate, - ['@type'] = type, - ['@job'] = xPlayer.job.name, - ['@stored'] = true - }, function (rowsChanged) + MySQL.insert('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (?, ?, ?, ?, ?, ?)', {xPlayer.identifier, json.encode(vehicleProps), vehicleProps.plate, type, xPlayer.job.name, true}, + function (rowsChanged) cb(true) end) else @@ -194,46 +188,32 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb end end) -ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(source, cb, nearbyVehicles) +ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(source, cb, plates) local xPlayer = ESX.GetPlayerFromId(source) - local foundPlate, foundNum - for k,v in ipairs(nearbyVehicles) do - local result = MySQL.Sync.fetchAll('SELECT plate FROM owned_vehicles WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = v.plate, - ['@job'] = xPlayer.job.name - }) + local plate = MySQL.scalar.await('SELECT plate FROM owned_vehicles WHERE owner = ? AND plate IN (?) AND job = ?', {xPlayer.identifier, plates, xPlayer.job.name}) - if result[1] then - foundPlate, foundNum = result[1].plate, k - break - end - end - - if not foundPlate then - cb(false) - else - MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = true WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = foundPlate, - ['@job'] = xPlayer.job.name - }, function (rowsChanged) + if plate then + MySQL.update('UPDATE owned_vehicles SET `stored` = true WHERE owner = ? AND plate = ? AND job = ?', {xPlayer.identifier, plate, xPlayer.job.name}, + function(rowsChanged) if rowsChanged == 0 then cb(false) else - cb(true, foundNum) + cb(plate) end end) + else + cb(false) end end) function getPriceFromHash(vehicleHash, jobGrade, type) local vehicles = Config.AuthorizedVehicles[type][jobGrade] - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == vehicleHash then - return v.price + for i = 1, #vehicles do + local vehicle = vehicles[i] + if GetHashKey(vehicle.model) == vehicleHash then + return vehicle.price end end @@ -306,10 +286,7 @@ end) ESX.RegisterServerCallback('esx_ambulancejob:getDeathStatus', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchScalar('SELECT is_dead FROM users WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(isDead) - + MySQL.scalar('SELECT is_dead FROM users WHERE identifier = ?', {xPlayer.identifier}, function(isDead) if isDead then print(('[esx_ambulancejob] [^2INFO^7] "%s" attempted combat logging'):format(xPlayer.identifier)) end @@ -323,9 +300,6 @@ AddEventHandler('esx_ambulancejob:setDeathStatus', function(isDead) local xPlayer = ESX.GetPlayerFromId(source) if type(isDead) == 'boolean' then - MySQL.Sync.execute('UPDATE users SET is_dead = @isDead WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier, - ['@isDead'] = isDead - }) + MySQL.update('UPDATE users SET is_dead = ? WHERE identifier = ?', {isDead, xPlayer.identifier}) end end) diff --git a/[esx_addons]/esx_bankerjob/server/main.lua b/[esx_addons]/esx_bankerjob/server/main.lua index 9af78dbf..394d5fcc 100644 --- a/[esx_addons]/esx_bankerjob/server/main.lua +++ b/[esx_addons]/esx_bankerjob/server/main.lua @@ -56,7 +56,7 @@ end) function CalculateBankSavings(d, h, m) local asyncTasks = {} - MySQL.Async.fetchAll('SELECT * FROM addon_account_data WHERE account_name = @account_name', { + MySQL.query('SELECT * FROM addon_account_data WHERE account_name = @account_name', { ['@account_name'] = 'bank_savings' }, function(result) local bankInterests = 0 @@ -80,7 +80,7 @@ function CalculateBankSavings(d, h, m) local scope = function(newMoney, owner) table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE owner = @owner AND account_name = @account_name', { + MySQL.update('UPDATE addon_account_data SET money = @money WHERE owner = @owner AND account_name = @account_name', { ['@money'] = newMoney, ['@owner'] = owner, ['@account_name'] = 'bank_savings', diff --git a/[esx_addons]/esx_billing/server/main.lua b/[esx_addons]/esx_billing/server/main.lua index 92ef1283..7b5853b5 100644 --- a/[esx_addons]/esx_billing/server/main.lua +++ b/[esx_addons]/esx_billing/server/main.lua @@ -7,25 +7,13 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la if amount > 0 and xTarget then TriggerEvent('esx_addonaccount:getSharedAccount', sharedAccountName, function(account) if account then - MySQL.Async.execute('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', { - ['@identifier'] = xTarget.identifier, - ['@sender'] = xPlayer.identifier, - ['@target_type'] = 'society', - ['@target'] = sharedAccountName, - ['@label'] = label, - ['@amount'] = amount - }, function(rowsChanged) + MySQL.insert('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)', {xTarget.identifier, xPlayer.identifier, 'society', sharedAccountName, label, amount}, + function(rowsChanged) xTarget.showNotification(_U('received_invoice')) end) else - MySQL.Async.execute('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', { - ['@identifier'] = xTarget.identifier, - ['@sender'] = xPlayer.identifier, - ['@target_type'] = 'player', - ['@target'] = xPlayer.identifier, - ['@label'] = label, - ['@amount'] = amount - }, function(rowsChanged) + MySQL.insert('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)', {xTarget.identifier, xPlayer.identifier, 'player', xPlayer.identifier, label, amount}, + function(rowsChanged) xTarget.showNotification(_U('received_invoice')) end) end @@ -36,9 +24,8 @@ end) ESX.RegisterServerCallback('esx_billing:getBills', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT amount, id, label FROM billing WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) + MySQL.query('SELECT amount, id, label FROM billing WHERE identifier = ?', {xPlayer.identifier}, + function(result) cb(result) end) end) @@ -47,9 +34,8 @@ ESX.RegisterServerCallback('esx_billing:getTargetBills', function(source, cb, ta local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.Async.fetchAll('SELECT amount, id, label FROM billing WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) + MySQL.query('SELECT amount, id, label FROM billing WHERE identifier = ?', {xPlayer.identifier}, + function(result) cb(result) end) else @@ -60,19 +46,17 @@ end) ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT sender, target_type, target, amount FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(result) - if result[1] then - local amount = result[1].amount - local xTarget = ESX.GetPlayerFromIdentifier(result[1].sender) + MySQL.single('SELECT sender, target_type, target, amount FROM billing WHERE id = ?', {billId}, + function(result) + if result then + local amount = result.amount + local xTarget = ESX.GetPlayerFromIdentifier(result.sender) - if result[1].target_type == 'player' then + if result.target_type == 'player' then if xTarget then if xPlayer.getMoney() >= amount then - MySQL.Async.execute('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.update('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeMoney(amount) xTarget.addMoney(amount) @@ -84,9 +68,8 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) cb() end) elseif xPlayer.getAccount('bank').money >= amount then - MySQL.Async.execute('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.update('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeAccountMoney('bank', amount) xTarget.addAccountMoney('bank', amount) @@ -109,9 +92,8 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) else TriggerEvent('esx_addonaccount:getSharedAccount', result[1].target, function(account) if xPlayer.getMoney() >= amount then - MySQL.Async.execute('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.update('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeMoney(amount) account.addMoney(amount) @@ -125,9 +107,8 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) cb() end) elseif xPlayer.getAccount('bank').money >= amount then - MySQL.Async.execute('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.update('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeAccountMoney('bank', amount) account.addMoney(amount) diff --git a/[esx_addons]/esx_boat/server/main.lua b/[esx_addons]/esx_boat/server/main.lua index 1b8479ff..410d1414 100644 --- a/[esx_addons]/esx_boat/server/main.lua +++ b/[esx_addons]/esx_boat/server/main.lua @@ -3,7 +3,7 @@ MySQL.ready(function() end) function ParkBoats() - MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = true WHERE `stored` = false AND type = @type', { + MySQL.update('UPDATE owned_vehicles SET `stored` = true WHERE `stored` = false AND type = @type', { ['@type'] = 'boat' }, function (rowsChanged) if rowsChanged > 0 then @@ -24,7 +24,7 @@ ESX.RegisterServerCallback('esx_boat:buyBoat', function(source, cb, vehicleProps if xPlayer.getMoney() >= price then xPlayer.removeMoney(price) - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle, type, `stored`) VALUES (@owner, @plate, @vehicle, @type, @stored)', { + MySQL.update('INSERT INTO owned_vehicles (owner, plate, vehicle, type, `stored`) VALUES (@owner, @plate, @vehicle, @type, @stored)', { ['@owner'] = xPlayer.identifier, ['@plate'] = vehicleProps.plate, ['@vehicle'] = json.encode(vehicleProps), @@ -43,7 +43,7 @@ RegisterServerEvent('esx_boat:takeOutVehicle') AddEventHandler('esx_boat:takeOutVehicle', function(plate) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = @stored WHERE owner = @owner AND plate = @plate', { + MySQL.update('UPDATE owned_vehicles SET `stored` = @stored WHERE owner = @owner AND plate = @plate', { ['@stored'] = false, ['@owner'] = xPlayer.identifier, ['@plate'] = plate @@ -57,7 +57,7 @@ end) ESX.RegisterServerCallback('esx_boat:storeVehicle', function (source, cb, plate) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = @stored WHERE owner = @owner AND plate = @plate', { + MySQL.update('UPDATE owned_vehicles SET `stored` = @stored WHERE owner = @owner AND plate = @plate', { ['@stored'] = true, ['@owner'] = xPlayer.identifier, ['@plate'] = plate @@ -73,7 +73,7 @@ end) ESX.RegisterServerCallback('esx_boat:getGarage', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT vehicle FROM owned_vehicles WHERE owner = @owner AND type = @type AND `stored` = @stored', { + MySQL.query('SELECT vehicle FROM owned_vehicles WHERE owner = @owner AND type = @type AND `stored` = @stored', { ['@owner'] = xPlayer.identifier, ['@type'] = 'boat', ['@stored'] = true diff --git a/[esx_addons]/esx_datastore/server/classes/datastore.lua b/[esx_addons]/esx_datastore/server/classes/datastore.lua index 382689d8..73611443 100644 --- a/[esx_addons]/esx_datastore/server/classes/datastore.lua +++ b/[esx_addons]/esx_datastore/server/classes/datastore.lua @@ -68,16 +68,9 @@ function CreateDataStore(name, owner, data) local timeoutCallback = ESX.SetTimeout(10000, function() if self.owner == nil then - MySQL.Async.execute('UPDATE datastore_data SET data = @data WHERE name = @name', { - ['@data'] = json.encode(self.data), - ['@name'] = self.name, - }) + MySQL.update('UPDATE datastore_data SET data = ? WHERE name = ?', {json.encode(self.data), self.name}) else - MySQL.Async.execute('UPDATE datastore_data SET data = @data WHERE name = @name and owner = @owner', { - ['@data'] = json.encode(self.data), - ['@name'] = self.name, - ['@owner'] = self.owner, - }) + MySQL.update('UPDATE datastore_data SET data = ? WHERE name = ? and owner = ?', {json.encode(self.data), self.name, self.owner}) end end) diff --git a/[esx_addons]/esx_datastore/server/main.lua b/[esx_addons]/esx_datastore/server/main.lua index 606d12b3..d1eafd78 100644 --- a/[esx_addons]/esx_datastore/server/main.lua +++ b/[esx_addons]/esx_datastore/server/main.lua @@ -1,41 +1,33 @@ local DataStores, DataStoresIndex, SharedDataStores = {}, {}, {} -MySQL.ready(function() - local result = MySQL.Sync.fetchAll('SELECT * FROM datastore') +AddEventHandler('onResourceStart', function(resourceName) + if resourceName == GetCurrentResourceName() then + local dataStore = MySQL.query.await('SELECT * FROM datastore_data LEFT JOIN datastore ON datastore_data.name = datastore.name UNION SELECT * FROM datastore_data RIGHT JOIN datastore ON datastore_data.name = datastore.name') - for i=1, #result, 1 do - local name, label, shared = result[i].name, result[i].label, result[i].shared - local result2 = MySQL.Sync.fetchAll('SELECT * FROM datastore_data WHERE name = @name', { - ['@name'] = name - }) - - if shared == 0 then - table.insert(DataStoresIndex, name) - DataStores[name] = {} - - for j=1, #result2, 1 do - local storeName = result2[j].name - local storeOwner = result2[j].owner - local storeData = (result2[j].data == nil and {} or json.decode(result2[j].data)) - local dataStore = CreateDataStore(storeName, storeOwner, storeData) - - table.insert(DataStores[name], dataStore) - end - else - local data - - if #result2 == 0 then - MySQL.Sync.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, NULL, \'{}\')', { - ['@name'] = name - }) - - data = {} + local newData = {} + for i = 1, #dataStore do + local data = dataStore[i] + if data.shared == 0 then + if not DataStores[data.name] then + DataStoresIndex[#DataStoresIndex + 1] = data.name + DataStores[data.name] = {} + end + DataStores[data.name][#DataStores[data.name] + 1] = CreateDataStore(data.name, data.owner, data.data) else - data = json.decode(result2[1].data) + if data.data then + SharedDataStores[data.name] = CreateDataStore(data.name, nil, data.data) + else + newData[#newData + 1] = {data.name, '\'{}\''} + end end + end - local dataStore = CreateDataStore(name, nil, data) - SharedDataStores[name] = dataStore + if next(newData) then + MySQL.prepare('INSERT INTO datastore_data (name, data) VALUES (?, ?)', newData) + for i = 1, #newData do + local new = newData[i] + SharedDataStores[new[1]] = CreateDataStore(new[1], nil, new[2]) + end end end end) @@ -80,14 +72,9 @@ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local dataStore = GetDataStore(name, xPlayer.identifier) if not dataStore then - MySQL.Async.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', { - ['@name'] = name, - ['@owner'] = xPlayer.identifier, - ['@data'] = '{}' - }) + MySQL.insert('INSERT INTO datastore_data (name, owner, data) VALUES (?, ?, ?)', {name, xPlayer.identifier, '{}'}) - dataStore = CreateDataStore(name, xPlayer.identifier, {}) - table.insert(DataStores[name], dataStore) + DataStores[name][#DataStores[name] + 1] = CreateDataStore(name, xPlayer.identifier, {}) end end end) diff --git a/[esx_addons]/esx_garage/server/main.lua b/[esx_addons]/esx_garage/server/main.lua index 0cd7bff1..b7517e82 100644 --- a/[esx_addons]/esx_garage/server/main.lua +++ b/[esx_addons]/esx_garage/server/main.lua @@ -5,7 +5,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) if vehicleProps == false then - MySQL.Async.execute('DELETE FROM `user_parkings` WHERE `identifier` = @identifier AND `garage` = @garage AND zone = @zone', + MySQL.update('DELETE FROM `user_parkings` WHERE `identifier` = @identifier AND `garage` = @garage AND zone = @zone', { ['@identifier'] = xPlayer.identifier, ['@garage'] = garage; @@ -14,7 +14,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) xPlayer.showNotification(_U('veh_released')) end) else - MySQL.Async.execute('INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', + MySQL.update('INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', { ['@identifier'] = xPlayer.identifier, ['@garage'] = garage; @@ -28,7 +28,7 @@ end) RegisterServerEvent('esx_garage:updateOwnedVehicle') AddEventHandler('esx_garage:updateOwnedVehicle', function(vehicleProps) - MySQL.Async.execute('UPDATE owned_vehicles SET vehicle = @vehicle WHERE plate = @plate', { + MySQL.update('UPDATE owned_vehicles SET vehicle = @vehicle WHERE plate = @plate', { ['@plate'] = vehicleProps.plate, ['@vehicle'] = json.encode(vehicleProps) }) @@ -37,7 +37,7 @@ end) ESX.RegisterServerCallback('esx_vehicleshop:getVehiclesInGarage', function(source, cb, garage) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM `user_parkings` WHERE `identifier` = @identifier AND garage = @garage', + MySQL.query('SELECT * FROM `user_parkings` WHERE `identifier` = @identifier AND garage = @garage', { ['@identifier'] = xPlayer.identifier, ['@garage'] = garage diff --git a/[esx_addons]/esx_joblisting/server/main.lua b/[esx_addons]/esx_joblisting/server/main.lua index 1f1a3753..732010e5 100644 --- a/[esx_addons]/esx_joblisting/server/main.lua +++ b/[esx_addons]/esx_joblisting/server/main.lua @@ -1,7 +1,7 @@ local availableJobs = {} MySQL.ready(function() - MySQL.Async.fetchAll('SELECT name, label FROM jobs WHERE whitelisted = @whitelisted', { + MySQL.query('SELECT name, label FROM jobs WHERE whitelisted = @whitelisted', { ['@whitelisted'] = false }, function(result) for i=1, #result, 1 do diff --git a/[esx_addons]/esx_jobs/jobs/fisherman.lua b/[esx_addons]/esx_jobs/jobs/fisherman.lua index cbad08c0..26186520 100644 --- a/[esx_addons]/esx_jobs/jobs/fisherman.lua +++ b/[esx_addons]/esx_jobs/jobs/fisherman.lua @@ -149,7 +149,6 @@ Config.Jobs.fisherman = { Pos = {x = -1012.64, y = -1354.62, z = 5.54}, Color = {r = 204, g = 204, b = 0}, Size = {x = 5.0, y = 5.0, z = 3.0}, - Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, Name = _U('delivery_point'), diff --git a/[esx_addons]/esx_jobs/jobs/miner.lua b/[esx_addons]/esx_jobs/jobs/miner.lua index edbffb6d..58c45cf3 100644 --- a/[esx_addons]/esx_jobs/jobs/miner.lua +++ b/[esx_addons]/esx_jobs/jobs/miner.lua @@ -196,7 +196,6 @@ Config.Jobs.miner = { Pos = {x = -148.78, y = -1040.38, z = 26.27}, Color = {r = 204, g = 204, b = 0}, Size = {x = 5.0, y = 5.0, z = 3.0}, - Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, Name = _U('m_sell_iron'), @@ -222,7 +221,6 @@ Config.Jobs.miner = { Pos = {x = 261.48, y = 207.35, z = 109.28}, Color = {r = 204, g = 204, b = 0}, Size = {x = 5.0, y = 5.0, z = 3.0}, - Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, Name = _U('m_sell_gold'), @@ -248,7 +246,6 @@ Config.Jobs.miner = { Pos = {x = -621.04, y = -228.53, z = 37.05}, Color = {r = 204, g = 204, b = 0}, Size = {x = 5.0, y = 5.0, z = 3.0}, - Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, Name = _U('m_sell_diamond'), diff --git a/[esx_addons]/esx_license/server/main.lua b/[esx_addons]/esx_license/server/main.lua index 65a75831..d92e485f 100644 --- a/[esx_addons]/esx_license/server/main.lua +++ b/[esx_addons]/esx_license/server/main.lua @@ -2,10 +2,8 @@ function AddLicense(target, type, cb) local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.Async.execute('INSERT INTO user_licenses (type, owner) VALUES (@type, @owner)', { - ['@type'] = type, - ['@owner'] = xPlayer.identifier - }, function(rowsChanged) + MySQL.insert('INSERT INTO user_licenses (type, owner) VALUES (?, ?)', {type, xPlayer.identifier}, + function(rowsChanged) if cb then cb() end @@ -21,10 +19,8 @@ function RemoveLicense(target, type, cb) local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.Async.execute('DELETE FROM user_licenses WHERE type = @type AND owner = @owner', { - ['@type'] = type, - ['@owner'] = xPlayer.identifier - }, function(rowsChanged) + MySQL.update('DELETE FROM user_licenses WHERE type = ? AND owner = ?', {type, xPlayer.identifier}, + function(rowsChanged) if cb then cb() end @@ -37,48 +33,18 @@ function RemoveLicense(target, type, cb) end function GetLicense(type, cb) - MySQL.Async.fetchAll('SELECT label FROM licenses WHERE type = @type', { - ['@type'] = type - }, function(result) - local data = { - type = type, - label = result[1].label - } - - cb(data) + MySQL.scalar('SELECT label FROM licenses WHERE type = ?', {type}, + function(result) + cb({type = type, label = result}) end) end function GetLicenses(target, cb) local xPlayer = ESX.GetPlayerFromId(target) - MySQL.Async.fetchAll('SELECT type FROM user_licenses WHERE owner = @owner', { - ['@owner'] = xPlayer.identifier - }, function(result) - local licenses, asyncTasks = {}, {} - - for i=1, #result, 1 do - local scope = function(type) - table.insert(asyncTasks, function(cb) - MySQL.Async.fetchAll('SELECT label FROM licenses WHERE type = @type', { - ['@type'] = type - }, function(result2) - table.insert(licenses, { - type = type, - label = result2[1].label - }) - - cb() - end) - end) - end - - scope(result[i].type) - end - - Async.parallel(asyncTasks, function(results) - cb(licenses) - end) + MySQL.query('SELECT user_licenses.type, licenses.label FROM user_licenses LEFT JOIN licenses ON user_licenses.type = licenses.type WHERE owner = ?', {xPlayer.identifier}, + function(result) + cb(result) end) end @@ -86,11 +52,9 @@ function CheckLicense(target, type, cb) local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.Async.fetchAll('SELECT COUNT(*) as count FROM user_licenses WHERE type = @type AND owner = @owner', { - ['@type'] = type, - ['@owner'] = xPlayer.identifier - }, function(result) - if tonumber(result[1].count) > 0 then + MySQL.scalar('SELECT type FROM user_licenses WHERE type = ? AND owner = ?', {type, xPlayer.identifier}, + function(result) + if result then cb(true) else cb(false) @@ -102,19 +66,9 @@ function CheckLicense(target, type, cb) end function GetLicensesList(cb) - MySQL.Async.fetchAll('SELECT type, label FROM licenses', { - ['@type'] = type - }, function(result) - local licenses = {} - - for i=1, #result, 1 do - table.insert(licenses, { - type = result[i].type, - label = result[i].label - }) - end - - cb(licenses) + MySQL.query('SELECT type, label FROM licenses', + function(result) + cb(result) end) end diff --git a/[esx_addons]/esx_lscustom/server/main.lua b/[esx_addons]/esx_lscustom/server/main.lua index f17279e3..766d8d13 100644 --- a/[esx_addons]/esx_lscustom/server/main.lua +++ b/[esx_addons]/esx_lscustom/server/main.lua @@ -37,17 +37,13 @@ RegisterServerEvent('esx_lscustom:refreshOwnedVehicle') AddEventHandler('esx_lscustom:refreshOwnedVehicle', function(vehicleProps) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT vehicle FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = vehicleProps.plate - }, function(result) - if result[1] then - local vehicle = json.decode(result[1].vehicle) + MySQL.single('SELECT vehicle FROM owned_vehicles WHERE plate = ?', {vehicleProps.plate}, + function(result) + if result then + local vehicle = json.decode(result.vehicle) if vehicleProps.model == vehicle.model then - MySQL.Async.execute('UPDATE owned_vehicles SET vehicle = @vehicle WHERE plate = @plate', { - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps) - }) + MySQL.update('UPDATE owned_vehicles SET vehicle = ? WHERE plate = ?', {json.encode(vehicleProps), vehicleProps.plate}) else print(('esx_lscustom: %s attempted to upgrade vehicle with mismatching vehicle model!'):format(xPlayer.identifier)) end @@ -57,20 +53,7 @@ end) ESX.RegisterServerCallback('esx_lscustom:getVehiclesPrices', function(source, cb) if not Vehicles then - MySQL.Async.fetchAll('SELECT * FROM vehicles', {}, function(result) - local vehicles = {} - - for i=1, #result, 1 do - table.insert(vehicles, { - model = result[i].model, - price = result[i].price - }) - end - - Vehicles = vehicles - cb(Vehicles) - end) - else - cb(Vehicles) + Vehicles = MySQL.query.await('SELECT model, price FROM vehicles') end + cb(Vehicles) end) \ No newline at end of file diff --git a/[esx_addons]/esx_mechanicjob/locales/fr.lua b/[esx_addons]/esx_mechanicjob/locales/fr.lua index 8ef7b414..692b71f7 100644 --- a/[esx_addons]/esx_mechanicjob/locales/fr.lua +++ b/[esx_addons]/esx_mechanicjob/locales/fr.lua @@ -73,7 +73,7 @@ Locales['fr'] = { ['not_enough_gas_can'] = 'Vous n\'avez ~r~pas assez~s~ de bouteille de gaz', ['assembling_blowtorch'] = 'Assemblage de ~b~chalumeaux~s~...', ['not_enough_repair_tools'] = 'Vous n\'avez ~r~pas assez~s~ d\'outils réparation', - ['assembling_blowtorch'] = 'Assemblage de ~b~kit réparation~s~...', + ['assembling_repair_kit'] = 'Assemblage de ~b~kit réparation~s~...', ['not_enough_body_tools'] = 'Vous n\'avez ~r~pas assez~s~ d\'outils carosserie', ['assembling_body_kit'] = 'Assemblage de ~b~kit carosserie~s~...', ['your_comp_earned'] = 'Votre société a ~g~gagné~s~ ~g~$', diff --git a/[esx_addons]/esx_multicharacter b/[esx_addons]/esx_multicharacter new file mode 160000 index 00000000..02352a8e --- /dev/null +++ b/[esx_addons]/esx_multicharacter @@ -0,0 +1 @@ +Subproject commit 02352a8e18176cb9f369ba608aab66ccf0311fe0 diff --git a/[esx_addons]/esx_multicharacter/LICENSE.md b/[esx_addons]/esx_multicharacter/LICENSE.md deleted file mode 100644 index f288702d..00000000 --- a/[esx_addons]/esx_multicharacter/LICENSE.md +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/[esx_addons]/esx_multicharacter/client/main.lua b/[esx_addons]/esx_multicharacter/client/main.lua deleted file mode 100644 index 242d159d..00000000 --- a/[esx_addons]/esx_multicharacter/client/main.lua +++ /dev/null @@ -1,326 +0,0 @@ -ESX = exports['es_extended']:getSharedObject() -if ESX.GetConfig().Multichar then - - Citizen.CreateThread(function() - while not ESX.PlayerLoaded do - Citizen.Wait(0) - if NetworkIsPlayerActive(PlayerId()) then - exports.spawnmanager:setAutoSpawn(false) - DoScreenFadeOut(0) - while not GetResourceState('esx_menu_default') == 'started' do - Citizen.Wait(0) - end - TriggerEvent("esx_multicharacter:SetupCharacters") - break - end - end - end) - - - local canRelog, cam, Spawned = true - local Characters = {} - - RegisterNetEvent('esx_multicharacter:SetupCharacters') - AddEventHandler('esx_multicharacter:SetupCharacters', function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} - Spawned = false - cam = CreateCam("DEFAULT_SCRIPTED_CAMERA", true) - local playerPed = PlayerPedId() - SetEntityCoords(playerPed, Config.Spawn.x, Config.Spawn.y, Config.Spawn.z, true, false, false, false) - SetEntityHeading(playerPed, Config.Spawn.w) - local offset = GetOffsetFromEntityInWorldCoords(playerPed, 0, 1.7, 0.4) - DoScreenFadeOut(0) - SetCamActive(cam, true) - RenderScriptCams(true, false, 1, true, true) - SetCamCoord(cam, offset.x, offset.y, offset.z) - PointCamAtCoord(cam, Config.Spawn.x, Config.Spawn.y, Config.Spawn.z + 1.3) - - ESX.UI.HUD.SetDisplay(0.0) - StartLoop() - ShutdownLoadingScreen() - ShutdownLoadingScreenNui() - TriggerEvent('esx:loadingScreenOff') - Citizen.Wait(200) - TriggerServerEvent("esx_multicharacter:SetupCharacters") - end) - - StartLoop = function() - hidePlayers = true - MumbleSetVolumeOverride(PlayerId(), 0.0) - Citizen.CreateThread(function() - local keys = {18, 27, 172, 173, 174, 175, 176, 177, 187, 188, 191, 201, 108, 109} - while hidePlayers do - DisableAllControlActions(0) - for i=1, #keys do - EnableControlAction(0, keys[i], true) - end - SetEntityVisible(PlayerPedId(), 0, 0) - SetLocalPlayerVisibleLocally(1) - SetPlayerInvincible(PlayerId(), 1) - ThefeedHideThisFrame() - HideHudComponentThisFrame(11) - HideHudComponentThisFrame(12) - HideHudComponentThisFrame(21) - HideHudAndRadarThisFrame() - Citizen.Wait(3) - local vehicles = GetGamePool('CVehicle') - for i=1, #vehicles do - SetEntityLocallyInvisible(vehicles[i]) - end - end - local playerId, playerPed = PlayerId(), PlayerPedId() - MumbleSetVolumeOverride(playerId, -1.0) - SetEntityVisible(playerPed, 1, 0) - SetPlayerInvincible(playerId, 0) - FreezeEntityPosition(playerPed, false) - Citizen.Wait(10000) - canRelog = true - end) - Citizen.CreateThread(function() - local playerPool = {} - while hidePlayers do - local players = GetActivePlayers() - for i=1, #players do - local player = players[i] - if player ~= PlayerId() and not playerPool[player] then - playerPool[player] = true - NetworkConcealPlayer(players[player], true, true) - end - end - Citizen.Wait(500) - end - for i=1, #playerPool do - NetworkConcealPlayer(playerPool[i], false, false) - end - end) - end - - SetupCharacter = function(index) - if Spawned == false then - exports.spawnmanager:spawnPlayer({ - x = Config.Spawn.x, - y = Config.Spawn.y, - z = Config.Spawn.z, - heading = Config.Spawn.w, - model = Characters[index].model or `mp_m_freemode_01`, - skipFade = true - }, function() - canRelog = false - if Characters[index] then - local skin = Characters[index].skin or Config.Default - if not Characters[index].model then - if Characters[index].sex == _('female') then skin.sex = 1 else skin.sex = 0 end - end - TriggerEvent('skinchanger:loadSkin', skin) - end - DoScreenFadeIn(400) - end) - repeat Citizen.Wait(200) until not IsScreenFadedOut() - - elseif Characters[index] and Characters[index].skin then - if Characters[Spawned] and Characters[Spawned].model then - RequestModel(Characters[index].model) - while not HasModelLoaded(Characters[index].model) do - RequestModel(Characters[index].model) - Citizen.Wait(0) - end - SetPlayerModel(PlayerId(), Characters[index].model) - SetModelAsNoLongerNeeded(Characters[index].model) - end - TriggerEvent('skinchanger:loadSkin', Characters[index].skin) - end - Spawned = index - local playerPed = PlayerPedId() - FreezeEntityPosition(PlayerPedId(), true) - SetPedAoBlobRendering(playerPed, true) - SetEntityAlpha(playerPed, 255) - SendNUIMessage({ - action = "openui", - character = Characters[Spawned] - }) - end - - RegisterNetEvent('esx_multicharacter:SetupUI') - AddEventHandler('esx_multicharacter:SetupUI', function(data) - DoScreenFadeOut(0) - Characters = data - local elements = {} - local Character = next(Characters) - - if Character == nil then - SendNUIMessage({ - action = "closeui" - }) - exports.spawnmanager:spawnPlayer({ - x = Config.Spawn.x, - y = Config.Spawn.y, - z = Config.Spawn.z, - heading = Config.Spawn.w, - model = `mp_m_freemode_01`, - skipFade = true - }, function() - canRelog = false - DoScreenFadeIn(400) - Citizen.Wait(400) - local playerPed = PlayerPedId() - SetPedAoBlobRendering(playerPed, false) - SetEntityAlpha(playerPed, 0) - TriggerServerEvent('esx_multicharacter:CharacterChosen', 1, true) - TriggerEvent('esx_identity:showRegisterIdentity') - end) - else - for k,v in pairs(Characters) do - if not v.model and v.skin then - if v.skin.model then v.model = v.skin.model elseif v.skin.sex == 1 then v.model = `mp_f_freemode_01` else v.model = `mp_m_freemode_01` end - end - if Spawned == false then SetupCharacter(Character) end - local label = v.firstname..' '..v.lastname - elements[#elements+1] = {label = label, value = v.id} - end - if #elements < Config.Slots then - elements[#elements+1] = {label = _('create_char'), value = (#elements+1), new = true} - end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'selectchar', { - title = _('select_char'), - align = 'top-left', - elements = elements - }, function(data, menu) - local elements = {} - if not data.current.new then - elements[1] = {label = _('char_play'), action = 'play', value = data.current.value} - elements[2] = {label = _('char_delete'), action = 'delete', value = data.current.value} - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'choosechar', { - title = _('select_char'), - align = 'top-left', - elements = elements - }, function(data, menu) - if data.current.action == 'play' then - ESX.UI.Menu.CloseAll() - SendNUIMessage({ - action = "closeui" - }) - TriggerServerEvent('esx_multicharacter:CharacterChosen', data.current.value, false) - else - local elements2 = {} - elements2[1] = {label = _('cancel')} - elements2[2] = {label = _('confirm'), value = data.current.value} - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'deletechar', { - title = _('delete_label', Characters[data.current.value].firstname, Characters[data.current.value].lastname), - align = 'center', - elements = elements2 - }, function(data, menu) - if data.current.value then - TriggerServerEvent('esx_multicharacter:DeleteCharacter', data.current.value) - Spawned = false - ESX.UI.Menu.CloseAll() - else - menu.close() - end - end, function(data, menu) - menu.close() - end) - end - end, function(data, menu) - menu.close() - end) - else - ESX.UI.Menu.CloseAll() - local GetSlot = function() - for i=1, Config.Slots do - if not Characters[i] then - return i - end - end - end - local slot = GetSlot() - TriggerServerEvent('esx_multicharacter:CharacterChosen', slot, true) - TriggerEvent('esx_identity:showRegisterIdentity') - end - end, function(data, menu) - menu.refresh() - end, function(data, menu) - if data.current.new then - local playerPed = PlayerPedId() - SetPedAoBlobRendering(playerPed, false) - SetEntityAlpha(playerPed, 0) - SendNUIMessage({ - action = "closeui" - }) - else - SetupCharacter(data.current.value) - local playerPed = PlayerPedId() - SetPedAoBlobRendering(playerPed, true) - ResetEntityAlpha(playerPed) - end - end) - end - end) - - RegisterNetEvent('esx:playerLoaded') - AddEventHandler('esx:playerLoaded', function(playerData, isNew, skin) - local spawn = playerData.coords - if isNew or not skin or #skin == 1 then - local finished = false - local sex = skin.sex or 0 - if sex == 0 then model = `mp_m_freemode_01` else model = `mp_f_freemode_01` end - RequestModel(model) - while not HasModelLoaded(model) do - RequestModel(model) - Citizen.Wait(0) - end - SetPlayerModel(PlayerId(), model) - SetModelAsNoLongerNeeded(model) - skin = Config.Default - skin.sex = sex - TriggerEvent('skinchanger:loadSkin', skin, function() - playerPed = PlayerPedId() - SetPedAoBlobRendering(playerPed, true) - ResetEntityAlpha(playerPed) - TriggerEvent('esx_skin:openSaveableMenu', function() - finished = true end, function() finished = true - end) - end) - repeat Citizen.Wait(200) until finished - end - DoScreenFadeOut(100) - repeat Citizen.Wait(200) until IsScreenFadedOut() - SetCamActive(cam, false) - RenderScriptCams(false, false, 0, true, true) - cam = nil - local playerPed = PlayerPedId() - FreezeEntityPosition(playerPed, true) - SetEntityCoords(playerPed, spawn.x, spawn.y, spawn.z-1.3, true, false, false, false) - SetEntityHeading(playerPed, spawn.heading) - if not isNew then TriggerEvent('skinchanger:loadSkin', skin or Characters[Spawned].skin) end - Citizen.Wait(400) - DoScreenFadeIn(400) - repeat Citizen.Wait(200) until not IsScreenFadedOut() - TriggerServerEvent('esx:onPlayerSpawn') - TriggerEvent('esx:onPlayerSpawn') - TriggerEvent('playerSpawned') - TriggerEvent('esx:restoreLoadout') - Characters, hidePlayers = {}, false - end) - - RegisterNetEvent('esx:onPlayerLogout') - AddEventHandler('esx:onPlayerLogout', function() - DoScreenFadeOut(0) - Spawned = false - TriggerEvent("esx_multicharacter:SetupCharacters") - TriggerEvent('esx_skin:resetFirstSpawn') - end) - - if Config.Relog then - RegisterCommand('relog', function(source, args, rawCommand) - if canRelog == true then - canRelog = false - TriggerServerEvent('esx_multicharacter:relog') - ESX.SetTimeout(10000, function() - canRelog = true - end) - end - end) - end - -end diff --git a/[esx_addons]/esx_multicharacter/config.lua b/[esx_addons]/esx_multicharacter/config.lua deleted file mode 100644 index 0dff5211..00000000 --- a/[esx_addons]/esx_multicharacter/config.lua +++ /dev/null @@ -1,110 +0,0 @@ -Config = {} -Config.Locale = 'en' - -Config.Slots = 4 -Config.Spawn = vector4(-113.7, 565.3, 195.2, 0) -- Sets the location for character selection --- To set the spawn location for new characters, modify the default value in the `users` SQL table - --------------------- --- Do not use unless you are prepared to adjust your resources to correctly reset data --- Information: https://github.com/thelindat/esx_multicharacter#relogging -Config.Relog = false --------------------- - -Config.Default = { - mom = 21, - dad = 0, - face_md_weight = 50, - skin_md_weight = 50, - nose_1 = 0, - nose_2 = 0, - nose_3 = 0, - nose_4 = 0, - nose_5 = 0, - nose_6 = 0, - cheeks_1 = 0, - cheeks_2 = 0, - cheeks_3 = 0, - lip_thickness = 0, - jaw_1 = 0, - jaw_2 = 0, - chin_1 = 0, - chin_2 = 0, - chin_13 = 0, - chin_4 = 0, - neck_thickness = 0, - hair_1 = 0, - hair_2 = 0, - hair_color_1 = 0, - hair_color_2 = 0, - tshirt_1 = 0, - tshirt_2 = 0, - torso_1 = 0, - torso_2 = 0, - decals_1 = 0, - decals_2 = 0, - arms = 0, - arms_2 = 0, - pants_1 = 0, - pants_2 = 0, - shoes_1 = 0, - shoes_2 = 0, - mask_1 = 0, - mask_2 = 0, - bproof_1 = 0, - bproof_2 = 0, - chain_1 = 0, - chain_2 = 0, - helmet_1 = -1, - helmet_2 = 0, - glasses_1 = 0, - glasses_2 = 0, - watches_1 = -1, - watches_2 = 0, - bracelets_1 = -1, - bracelets_2 = 0, - bags_1 = 0, - bags_2 = 0, - eye_color = 0, - eye_squint = 0, - eyebrows_2 = 0, - eyebrows_1 = 0, - eyebrows_3 = 0, - eyebrows_4 = 0, - eyebrows_5 = 0, - eyebrows_6 = 0, - makeup_1 = 0, - makeup_2 = 0, - makeup_3 = 0, - makeup_4 = 0, - lipstick_1 = 0, - lipstick_2 = 0, - lipstick_3 = 0, - lipstick_4 = 0, - ears_1 = -1, - ears_2 = 0, - chest_1 = 0, - chest_2 = 0, - chest_3 = 0, - bodyb_1 = -1, - bodyb_2 = 0, - bodyb_3 = -1, - bodyb_4 = 0, - age_1 = 0, - age_2 = 0, - blemishes_1 = 0, - blemishes_2 = 0, - blush_1 = 0, - blush_2 = 0, - blush_3 = 0, - complexion_1 = 0, - complexion_2 = 0, - sun_1 = 0, - sun_2 = 0, - moles_1 = 0, - moles_2 = 0, - beard_1 = 0, - beard_2 = 0, - beard_3 = 0, - beard_4 = 0 -} diff --git a/[esx_addons]/esx_multicharacter/fxmanifest.lua b/[esx_addons]/esx_multicharacter/fxmanifest.lua deleted file mode 100644 index 617f933c..00000000 --- a/[esx_addons]/esx_multicharacter/fxmanifest.lua +++ /dev/null @@ -1,38 +0,0 @@ -fx_version 'adamant' -game 'gta5' -description 'https://github.com/thelindat/esx_multicharacter' -version '1.2.2' - -dependencies { - 'es_extended', - 'esx_menu_default', - 'esx_identity', - 'esx_skin' -} - -shared_scripts { - '@es_extended/locale.lua', - 'locales/*.lua', - 'config.lua' -} - -server_scripts { - '@es_extended/imports.lua', - '@mysql-async/lib/MySQL.lua', - 'server/*.lua' -} - -client_scripts { - 'client/*.lua' -} - -ui_page { - 'html/ui.html', -} - -files { - 'html/ui.html', - 'html/css/main.css', - 'html/js/app.js', - 'html/locales/*.js', -} diff --git a/[esx_addons]/esx_multicharacter/html/css/main.css b/[esx_addons]/esx_multicharacter/html/css/main.css deleted file mode 100644 index 60090d94..00000000 --- a/[esx_addons]/esx_multicharacter/html/css/main.css +++ /dev/null @@ -1,71 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@300;600&display=swap'); -* { - margin: 0; - padding: 0; - user-select: none; - color: rgb(255, 255, 255); - font-weight: 300; - font-size: 1.6vh; - font-family: Calibri, "Helvetica", san-serif; -} - -html { - overflow: hidden; -} - -p { - margin: 0 !important; -} - -body { - background: transparent; -} - -.main-container { - display:none; - position: absolute; - top: 50%; - right: 0; - transform: translate(0, -50%); - background: rgba(0,0,0,0.7); - margin-right: 1.5rem; -} - -.header { - position: absolute; - top: 5%; - left: 50%; - transform: translate(-50%); - font-size: 1.1rem; -} - -.footer { - position: absolute; - bottom: 5%; - left: 50%; - transform: translate(-50%); - font-size: 1.1rem; -} - -.character-box { - display: flex; - right: 0; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - line-height: 1.4rem; - height: calc(100vh - 6rem); - width: 20rem; - padding: 1rem; - border: 1px rgba(12,12,12,200) solid; - box-shadow: 0px 0px 4px 1px rgba(12,12,12,20); -} - -h1 { - font-family: 'Raleway', sans-serif; - padding-top: 2rem; - display: block; - font-size: 1.3rem; - font-weight: 600; -} diff --git a/[esx_addons]/esx_multicharacter/html/js/app.js b/[esx_addons]/esx_multicharacter/html/js/app.js deleted file mode 100644 index 22b5c92c..00000000 --- a/[esx_addons]/esx_multicharacter/html/js/app.js +++ /dev/null @@ -1,35 +0,0 @@ -var money = Intl.NumberFormat('en-US', { - style: 'currency', - currency: 'USD', - minimumFractionDigits: 0 -}); - -(() => { - Kashacter = {}; - - Kashacter.ShowUI = function(data) { - $('body').css({"display":"block"}); - $('.main-container').css({"display":"block"}); - $('[data-charid=1]').html('

' + `${translate.name} ` + '

' + data.firstname +' '+ data.lastname +'

' + `${translate.job} ` + '

'+ data.job +' '+ data.job_grade +'

' + `${translate.money} ` + '

'+ money.format(data.money) +'

' + `${translate.bank} ` + '

'+ money.format(data.bank) +'

' + `${translate.dob} ` + '

'+ data.dateofbirth +'

' + `${translate.gender} ` + '

'+ data.sex +'

').attr("data-ischar", "true"); - }; - - Kashacter.CloseUI = function() { - $('body').css({"display":"none"}); - $('.main-container').css({"display":"none"}); - $('[data-charid=1]').html('

'); - }; - - window.onload = function(e) { - window.addEventListener('message', function(event) { - switch(event.data.action) { - case 'openui': - Kashacter.ShowUI(event.data.character); - break; - case 'closeui': - Kashacter.CloseUI(); - break; - } - }) - } - -})(); diff --git a/[esx_addons]/esx_multicharacter/html/locales/cs.js b/[esx_addons]/esx_multicharacter/html/locales/cs.js deleted file mode 100644 index cc84dedc..00000000 --- a/[esx_addons]/esx_multicharacter/html/locales/cs.js +++ /dev/null @@ -1,8 +0,0 @@ -const translate = new Object(); - -translate.name = "Jméno"; -translate.job = "Práce"; -translate.bank = "Banka"; -translate.money = "Peníze"; -translate.gender = "Pohlaví"; -translate.dob = "Datum narození"; diff --git a/[esx_addons]/esx_multicharacter/html/locales/de.js b/[esx_addons]/esx_multicharacter/html/locales/de.js deleted file mode 100644 index efd17188..00000000 --- a/[esx_addons]/esx_multicharacter/html/locales/de.js +++ /dev/null @@ -1,8 +0,0 @@ -const translate = new Object(); - -translate.name = "Name"; -translate.job = "Beruf"; -translate.bank = "Bankguthaben"; -translate.money = "Bargeld"; -translate.gender = "Geschlecht"; -translate.dob = "Geburtsdatum"; diff --git a/[esx_addons]/esx_multicharacter/html/locales/en.js b/[esx_addons]/esx_multicharacter/html/locales/en.js deleted file mode 100644 index 125dd3f0..00000000 --- a/[esx_addons]/esx_multicharacter/html/locales/en.js +++ /dev/null @@ -1,8 +0,0 @@ -const translate = new Object(); - -translate.name = "Name"; -translate.job = "Job"; -translate.bank = "Bank"; -translate.money = "Cash"; -translate.gender = "Gender"; -translate.dob = "Date of birth"; diff --git a/[esx_addons]/esx_multicharacter/html/locales/fr.js b/[esx_addons]/esx_multicharacter/html/locales/fr.js deleted file mode 100644 index 597a217d..00000000 --- a/[esx_addons]/esx_multicharacter/html/locales/fr.js +++ /dev/null @@ -1,8 +0,0 @@ -const translate = new Object(); - -translate.name = "Nom"; -translate.job = "Métier"; -translate.bank = "Banque"; -translate.money = "Argent"; -translate.gender = "Sexe"; -translate.dob = "Date de naissance"; diff --git a/[esx_addons]/esx_multicharacter/html/locales/pl.js b/[esx_addons]/esx_multicharacter/html/locales/pl.js deleted file mode 100644 index 07b27356..00000000 --- a/[esx_addons]/esx_multicharacter/html/locales/pl.js +++ /dev/null @@ -1,8 +0,0 @@ -const translate = new Object(); - -translate.name = "imię"; -translate.job = "Zajęcie"; -translate.bank = "Bank"; -translate.money = "Gotówka"; -translate.gender = "Seks"; -translate.dob = "Data urodzenia"; diff --git a/[esx_addons]/esx_multicharacter/html/locales/pt.js b/[esx_addons]/esx_multicharacter/html/locales/pt.js deleted file mode 100644 index c8eca4f8..00000000 --- a/[esx_addons]/esx_multicharacter/html/locales/pt.js +++ /dev/null @@ -1,8 +0,0 @@ -const translate = new Object(); - -translate.name = "Nome"; -translate.job = "Trabalho"; -translate.bank = "Banco"; -translate.money = "Dinheiro"; -translate.gender = "Género"; -translate.dob = "Data de Nascimento"; diff --git a/[esx_addons]/esx_multicharacter/html/locales/tr.js b/[esx_addons]/esx_multicharacter/html/locales/tr.js deleted file mode 100644 index ab820732..00000000 --- a/[esx_addons]/esx_multicharacter/html/locales/tr.js +++ /dev/null @@ -1,8 +0,0 @@ -const translate = new Object(); - -translate.name = "İsim"; -translate.job = "Meslek"; -translate.bank = "Banka"; -translate.money = "Nakit"; -translate.gender = "Cinsiyet"; -translate.dob = "Doğum Tarihi"; diff --git a/[esx_addons]/esx_multicharacter/html/ui.html b/[esx_addons]/esx_multicharacter/html/ui.html deleted file mode 100644 index 7b59ac89..00000000 --- a/[esx_addons]/esx_multicharacter/html/ui.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - -
-
ESX Legacy
-
-

-
-
- -
- - - - - - \ No newline at end of file diff --git a/[esx_addons]/esx_multicharacter/locales/cs.lua b/[esx_addons]/esx_multicharacter/locales/cs.lua deleted file mode 100644 index a9734076..00000000 --- a/[esx_addons]/esx_multicharacter/locales/cs.lua +++ /dev/null @@ -1,11 +0,0 @@ -Locales['cs'] = { - ['male'] = "Muž", - ['female'] = "Žena", - ['delete_label'] = "Vymazat %s %s?", - ['select_char'] = "Zvolit Postavu", - ['create_char'] = "Vytvořit novou postavu", - ['char_play'] = "Hrát za postavu", - ['char_delete'] = "Vymazat postavu", - ['cancel'] = "Zrušit", - ['confirm'] = "Potvrdit", -} diff --git a/[esx_addons]/esx_multicharacter/locales/de.lua b/[esx_addons]/esx_multicharacter/locales/de.lua deleted file mode 100644 index 654971af..00000000 --- a/[esx_addons]/esx_multicharacter/locales/de.lua +++ /dev/null @@ -1,11 +0,0 @@ -Locales['de'] = { - ['male'] = "Männlich", - ['female'] = "Weiblich", - ['delete_label'] = "Lösche %s %s?", - ['select_char'] = "Charakter auswählen", - ['create_char'] = "Neuen Charakter erstellen", - ['char_play'] = "Diesen Charakter spielen", - ['char_delete'] = "Diesen Charakter löschen", - ['cancel'] = "Abbrechen", - ['confirm'] = "Bestätigen", -} diff --git a/[esx_addons]/esx_multicharacter/locales/en.lua b/[esx_addons]/esx_multicharacter/locales/en.lua deleted file mode 100644 index f814d78a..00000000 --- a/[esx_addons]/esx_multicharacter/locales/en.lua +++ /dev/null @@ -1,11 +0,0 @@ -Locales['en'] = { - ['male'] = "Male", - ['female'] = "Female", - ['delete_label'] = "Delete %s %s?", - ['select_char'] = "Select Character", - ['create_char'] = "Create new character", - ['char_play'] = "Play this character", - ['char_delete'] = "Delete this character", - ['cancel'] = "Cancel", - ['confirm'] = "Confirm", -} diff --git a/[esx_addons]/esx_multicharacter/locales/pt.lua b/[esx_addons]/esx_multicharacter/locales/pt.lua deleted file mode 100644 index 04b828a3..00000000 --- a/[esx_addons]/esx_multicharacter/locales/pt.lua +++ /dev/null @@ -1,11 +0,0 @@ -Locales['pt'] = { - ['male'] = "Masculino", - ['female'] = "Feminino", - ['delete_label'] = "Eliminar %s %s?", - ['select_char'] = "Selecionar personagem", - ['create_char'] = "Criar novo personagem", - ['char_play'] = "Selecionar", - ['char_delete'] = "Eliminar personagem", - ['cancel'] = "Cancelar", - ['confirm'] = "Confirmar", -} diff --git a/[esx_addons]/esx_multicharacter/locales/tr.lua b/[esx_addons]/esx_multicharacter/locales/tr.lua deleted file mode 100644 index 8a3aa060..00000000 --- a/[esx_addons]/esx_multicharacter/locales/tr.lua +++ /dev/null @@ -1,11 +0,0 @@ -Locales['tr'] = { - ['male'] = "Erkek", - ['female'] = "Kadın", - ['delete_label'] = "Sil %s %s?", - ['select_char'] = "Karakter Seç", - ['create_char'] = "Yeni Karakter Oluştur", - ['char_play'] = "Bu Karakterle Oyna", - ['char_delete'] = "Bu Karakteri Sil", - ['cancel'] = "İptal", - ['confirm'] = "Onayla", -} diff --git a/[esx_addons]/esx_multicharacter/readme.md b/[esx_addons]/esx_multicharacter/readme.md deleted file mode 100644 index 7fb62877..00000000 --- a/[esx_addons]/esx_multicharacter/readme.md +++ /dev/null @@ -1,88 +0,0 @@ -### Requirements (ensure you are using the latest) -- [ESX Legacy](https://github.com/esx-framework/esx-legacy) -- [MySQL Async 3.3.2](https://github.com/brouznouf/fivem-mysql-async/releases/tag/3.3.2) -- [ESX Identity](https://github.com/esx-framework/esx_identity) -- [ESX Skin](https://github.com/esx-framework/esx_skin) -- [Spawnmanager](https://github.com/citizenfx/cfx-server-data/tree/master/resources/%5Bmanagers%5D/spawnmanager) - -### Installation -- Modify your ESX config with `Config.Multichar = true` -- Set your database name for `Config.Database` in server/main.lua -- All owner and identifier columns should be set to `VARCHAR(60)` to ensure correct data entry - - The resource will attempt to set columns automatically - -### Conflicts -* The following resources should not be used with ESX Legacy and can result in errors - - essentialmode - - basic-gamemode - - fivem-map-skater - - fivem-map-hipster - - default_spawnpoint - -### Common issues -#### Black screen / loading scripts - - Download and run all requirements - - Use a fresh spawnmanager as many people alter the code - - Ensure none of the conflicting resources are enabled -#### mysql-async duplicate entry - - You have not increased the VARCHAR size of the table holding identifiers - usually `owner` or `identifier` - -#### The menu interface is esx_menu_default - you can use any version if you want a different appearance -![image](https://user-images.githubusercontent.com/65407488/126976325-17cc3241-bb9e-451f-a6ed-610a8ef52fa5.png) - -### Relogging -- Do not enable this setting if you do not intend to properly set up relog support -- Requires the latest update for ESX Status (prevents multiple status ticks from running) -- Add the following events to resources that require support for relogging, or -- Add them to [@esx/imports.lua](https://github.com/esx-framework/es_extended/blob/legacy/imports.lua) (and use the imports in your resources) -```lua -RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true -end) - -RegisterNetEvent('esx:onPlayerLogout') -AddEventHandler('esx:onPlayerLogout', function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} -end) -``` -- Any threads using ESX.PlayerData in a loop should check if ESX.PlayerLoaded is true - - This ensures the resource does not error after relogging, or while on character selection - - Setup correctly you can break your loops and trigger them again after loading - - Refer to my [boilerplate](https://github.com/thelindat/esx_legacy_boilerplate) for more information and usage examples - -### Notes -- This resource is not compatible with ExtendedMode or previous versions of ESX -- Legacy, skin, and identity must be updated to at least the minimum commits specified above -- Characters are stored in the users table as `char#:license` - if you need to use a different identifier then you need to modify ESX itself -- Character deletion does not require manual entries for the tables to remove -- As characters are stored with unique identifiers, there is no excessive queries being executed - -### Kashacters -- This project is forked from the [kashacters multicharacter resource](https://github.com/FiveEYZ/esx_kashacter) -- Most of the code has been entirely rewritten -- KASH has given permission for this resource to use his code and the addition of a license -- The license obviously does not apply to previous versions and KASH has stated his resource is free to be used however - - - -## Notice -Copyright© 2021 Linden and KASH - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see https://www.gnu.org/licenses. - - -### Thanks to KASH, XxFri3ndlyxX, and all those who have contributed diff --git a/[esx_addons]/esx_multicharacter/server/functions.lua b/[esx_addons]/esx_multicharacter/server/functions.lua deleted file mode 100644 index a1312e0a..00000000 --- a/[esx_addons]/esx_multicharacter/server/functions.lua +++ /dev/null @@ -1,8 +0,0 @@ -GetJobs = function() - local jobs = {} - while next(jobs) == nil do - Citizen.Wait(250) - jobs = exports['es_extended']:getSharedObject().Jobs - end - return jobs -end \ No newline at end of file diff --git a/[esx_addons]/esx_multicharacter/server/main.lua b/[esx_addons]/esx_multicharacter/server/main.lua deleted file mode 100644 index ea74dafa..00000000 --- a/[esx_addons]/esx_multicharacter/server/main.lua +++ /dev/null @@ -1,132 +0,0 @@ -if not ESX then - SetTimeout(3000, function() print('[^3WARNING^7] Unable to start Multicharacter - your version of ESX is not compatible ') end) -elseif ESX.GetConfig().Multichar == true then - local IdentifierTables, Fetch = {}, -1 - - -- enter the name of your database here - Config.Database = 'es_extended' - - -- enter a prefix to prepend to all user identifiers (keep it short) - Config.Prefix = 'char' - - local SetupCharacters = function(playerId) - while Fetch == -1 do Citizen.Wait(500) end - local identifier = Config.Prefix..'%:'..ESX.GetIdentifier(playerId) - MySQL.Async.fetchAll(Fetch, { - identifier, - Config.Slots - }, function(result) - local characters = {} - for i=1, #result, 1 do - local job, grade = result[i].job or 'unemployed', tostring(result[i].job_grade) - if ESX.Jobs[job] and ESX.Jobs[job].grades[grade] then - if job ~= 'unemployed' then grade = ESX.Jobs[job].grades[grade].label else grade = '' end - job = ESX.Jobs[job].label - end - local accounts = json.decode(result[i].accounts) - local id = tonumber(string.sub(result[i].identifier, #Config.Prefix+1, string.find(result[i].identifier, ':')-1)) - characters[id] = { - id = id, - bank = accounts.bank, - money = accounts.money, - job = job, - job_grade = grade, - firstname = result[i].firstname, - lastname = result[i].lastname, - dateofbirth = result[i].dateofbirth, - skin = json.decode(result[i].skin) - } - if result[i].sex == 'm' then characters[id].sex = _('male') else characters[id].sex = _('female') end - end - TriggerClientEvent('esx_multicharacter:SetupUI', playerId, characters) - end) - end - - local DeleteCharacter = function(playerId, charid) - local identifier = Config.Prefix..charid..':'..ESX.GetIdentifier(playerId) - local counter = 0 - for k, v in pairs(IdentifierTables) do - MySQL.Async.execute("DELETE FROM "..v.table.." WHERE "..v.column.." = ?", { - identifier - }, function() - counter = counter + 1 - if counter == #IdentifierTables then - print(('[^2INFO^7] Player [%s] %s has deleted a character (%s)'):format(GetPlayerName(playerId), playerId, identifier)) - Citizen.Wait(100) - SetupCharacters(playerId) - end - end) - Citizen.Wait(5) - end - end - - MySQL.ready(function() - MySQL.Async.fetchAll('SELECT `TABLE_NAME`, `COLUMN_NAME`, `CHARACTER_MAXIMUM_LENGTH` FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ? AND (COLUMN_NAME = ? OR COLUMN_NAME = ?) ', { - Config.Database, 'identifier', 'owner' - }, function(result) - if result then - local varchar, varsize = {}, 0 - for k, v in pairs(result) do - if v.CHARACTER_MAXIMUM_LENGTH and v.CHARACTER_MAXIMUM_LENGTH >= 40 and v.CHARACTER_MAXIMUM_LENGTH < 60 then varchar[v.TABLE_NAME] = v.COLUMN_NAME varsize = varsize+1 end - table.insert(IdentifierTables, {table = v.TABLE_NAME, column = v.COLUMN_NAME}) - end - if next(varchar) then - for k, v in pairs(varchar) do - MySQL.Sync.execute("ALTER TABLE "..k.." MODIFY COLUMN "..v.." VARCHAR(60)") - end - print(('[^2INFO^7] Attempted to update ^5%s^7 columns to use VARCHAR(60)'):format(varsize)) - end - if not next(ESX.Jobs) then ESX.Jobs = GetJobs() end - Fetch = MySQL.Sync.store("SELECT `identifier`, `accounts`, `job`, `job_grade`, `firstname`, `lastname`, `dateofbirth`, `sex`, `skin` FROM `users` WHERE identifier LIKE ? LIMIT ?") - end - end) - end) - - RegisterServerEvent("esx_multicharacter:SetupCharacters") - AddEventHandler('esx_multicharacter:SetupCharacters', function() - SetupCharacters(source) - end) - - local awaitingRegistration = {} - RegisterServerEvent("esx_multicharacter:CharacterChosen") - AddEventHandler('esx_multicharacter:CharacterChosen', function(charid, isNew) - local src = source - if type(charid) == 'number' and string.len(charid) <= 2 and type(isNew) == 'boolean' then - if isNew then - awaitingRegistration[src] = charid - else - TriggerEvent('esx:onPlayerJoined', src, Config.Prefix..charid) - end - end - end) - - AddEventHandler('esx_identity:completedRegistration', function(playerId, data) - TriggerEvent('esx:onPlayerJoined', playerId, Config.Prefix..awaitingRegistration[playerId], data) - awaitingRegistration[playerId] = nil - end) - - AddEventHandler('playerDropped', function(reason) - awaitingRegistration[source] = nil - end) - - RegisterServerEvent("esx_multicharacter:DeleteCharacter") - AddEventHandler('esx_multicharacter:DeleteCharacter', function(charid) - local src = source - if type(charid) == "number" and string.len(charid) <= 2 then - DeleteCharacter(src, charid) - end - end) - - RegisterServerEvent("esx_multicharacter:relog") - AddEventHandler('esx_multicharacter:relog', function() - local src = source - TriggerEvent('esx:playerLogout', src) - end) - - RegisterCommand('forcelog', function(source, args, rawCommand) - TriggerEvent('esx:playerLogout', source) - end, true) - -else - SetTimeout(3000, function() print('[^3WARNING^7] Multicharacter is disabled - please check your ESX configuration') end) -end diff --git a/[esx_addons]/esx_phone/server/main.lua b/[esx_addons]/esx_phone/server/main.lua index 9f2c1053..71b4760b 100644 --- a/[esx_addons]/esx_phone/server/main.lua +++ b/[esx_addons]/esx_phone/server/main.lua @@ -22,7 +22,7 @@ function LoadPlayer(player) end end - MySQL.Async.fetchAll('SELECT phone_number FROM users WHERE identifier = @identifier', { + MySQL.query('SELECT phone_number FROM users WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }, function(result) local phoneNumber = result[1].phone_number @@ -30,7 +30,7 @@ function LoadPlayer(player) if phoneNumber == nil then phoneNumber = GenerateUniquePhoneNumber() - MySQL.Async.execute('UPDATE users SET phone_number = @phone_number WHERE identifier = @identifier', { + MySQL.update('UPDATE users SET phone_number = @phone_number WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier, ['@phone_number'] = phoneNumber }) @@ -53,7 +53,7 @@ function LoadPlayer(player) TriggerEvent('esx_phone:addSource', xPlayer.job.name, xPlayer.source) end - MySQL.Async.fetchAll('SELECT * FROM user_contacts WHERE identifier = @identifier ORDER BY name ASC', { + MySQL.query('SELECT * FROM user_contacts WHERE identifier = @identifier ORDER BY name ASC', { ['@identifier'] = xPlayer.identifier }, function(result2) for i=1, #result2, 1 do @@ -78,7 +78,7 @@ function GenerateUniquePhoneNumber() math.randomseed(GetGameTimer()) phoneNumber = math.random(10000, 99999) - local result = MySQL.Sync.fetchAll('SELECT COUNT(*) as count FROM users WHERE phone_number = @phoneNumber', { + local result = MySQL.query.await('SELECT COUNT(*) as count FROM users WHERE phone_number = @phoneNumber', { ['@phoneNumber'] = phoneNumber }) @@ -206,7 +206,7 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) return end - MySQL.Async.fetchAll('SELECT phone_number, identifier FROM users WHERE phone_number = @number', { + MySQL.query('SELECT phone_number, identifier FROM users WHERE phone_number = @number', { ['@number'] = phoneNumber }, function(result) if result[1] then @@ -234,7 +234,7 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) local xTarget = ESX.GetPlayerFromIdentifier(result[1].identifier) playerOnline = xTarget ~= nil - MySQL.Async.execute('INSERT INTO user_contacts (identifier, name, number) VALUES (@identifier, @name, @number)', { + MySQL.update('INSERT INTO user_contacts (identifier, name, number) VALUES (@identifier, @name, @number)', { ['@identifier'] = xPlayer.identifier, ['@name'] = contactName, ['@number'] = phoneNumber @@ -255,7 +255,7 @@ AddEventHandler('esx_phone:removePlayerContact', function(phoneNumber, contactNa local xPlayer = ESX.GetPlayerFromId(playerId) local foundNumber = false - MySQL.Async.fetchAll('SELECT phone_number FROM users WHERE phone_number = @number', { + MySQL.query('SELECT phone_number FROM users WHERE phone_number = @number', { ['@number'] = phoneNumber }, function(result) if result[1] then @@ -273,7 +273,7 @@ AddEventHandler('esx_phone:removePlayerContact', function(phoneNumber, contactNa xPlayer.set('contacts', contacts) - MySQL.Async.execute('DELETE FROM user_contacts WHERE identifier = @identifier AND name = @name AND number = @number', { + MySQL.update('DELETE FROM user_contacts WHERE identifier = @identifier AND name = @name AND number = @number', { ['@identifier'] = xPlayer.identifier, ['@name'] = contactName, ['@number'] = phoneNumber diff --git a/[esx_addons]/esx_policejob/client/vehicle.lua b/[esx_addons]/esx_policejob/client/vehicle.lua index 2a0d04b4..2a4cb456 100644 --- a/[esx_addons]/esx_policejob/client/vehicle.lua +++ b/[esx_addons]/esx_policejob/client/vehicle.lua @@ -118,17 +118,17 @@ function OpenVehicleSpawnerMenu(type, station, part, partNum) end function StoreNearbyVehicle(playerCoords) - local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} - - if #vehicles > 0 then - for k,v in ipairs(vehicles) do + local vehicles, plates, index = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {}, {} + if next(vehicles) then + for i = 1, #vehicles do + local vehicle = vehicles[i] + -- Make sure the vehicle we're saving is empty, or else it wont be deleted - if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then - table.insert(vehiclePlates, { - vehicle = v, - plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) - }) + if GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) then + local plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) + plates[#plates + 1] = plate + index[plate] = vehicle end end else @@ -136,27 +136,22 @@ function StoreNearbyVehicle(playerCoords) return end - ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(storeSuccess, foundNum) - if storeSuccess then - local vehicleId = vehiclePlates[foundNum] + ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(plate) + if plate then + local vehicleId = index[plate] local attempts = 0 - ESX.Game.DeleteVehicle(vehicleId.vehicle) - IsBusy = true + ESX.Game.DeleteVehicle(vehicleId) + local isBusy = true Citizen.CreateThread(function() - BeginTextCommandBusyspinnerOn('STRING') - AddTextComponentSubstringPlayerName(_U('garage_storing')) - EndTextCommandBusyspinnerOn(4) - - while IsBusy do - Citizen.Wait(100) + while isBusy do + Citizen.Wait(0) + drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) end - - BusyspinnerOff() end) -- Workaround for vehicle not deleting when other players are near it. - while DoesEntityExist(vehicleId.vehicle) do + while DoesEntityExist(vehicleId) do Citizen.Wait(500) attempts = attempts + 1 @@ -167,21 +162,22 @@ function StoreNearbyVehicle(playerCoords) vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0) if #vehicles > 0 then - for k,v in ipairs(vehicles) do - if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then - ESX.Game.DeleteVehicle(v) + for i = 1, #vehicles do + local vehicle = vehicles[i] + if ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) == plate then + ESX.Game.DeleteVehicle(vehicle) break end end end end - IsBusy = false + isBusy = false ESX.ShowNotification(_U('garage_has_stored')) else ESX.ShowNotification(_U('garage_has_notstored')) end - end, vehiclePlates) + end, plates) end function GetAvailableVehicleSpawnPoint(station, part, partNum) diff --git a/[esx_addons]/esx_policejob/localization/nl_esx_policejob.lua b/[esx_addons]/esx_policejob/localization/nl_esx_policejob.sql similarity index 100% rename from [esx_addons]/esx_policejob/localization/nl_esx_policejob.lua rename to [esx_addons]/esx_policejob/localization/nl_esx_policejob.sql diff --git a/[esx_addons]/esx_policejob/server/main.lua b/[esx_addons]/esx_policejob/server/main.lua index e2697099..0bfc2635 100644 --- a/[esx_addons]/esx_policejob/server/main.lua +++ b/[esx_addons]/esx_policejob/server/main.lua @@ -57,7 +57,7 @@ AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, -- does the target player have weapon? if targetXPlayer.hasWeapon(itemName) then - targetXPlayer.removeWeapon(itemName, amount) + targetXPlayer.removeWeapon(itemName) sourceXPlayer.addWeapon (itemName, amount) sourceXPlayer.showNotification(_U('you_confiscated_weapon', ESX.GetWeaponLabel(itemName), targetXPlayer.name, amount)) @@ -198,44 +198,36 @@ ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, end) ESX.RegisterServerCallback('esx_policejob:getFineList', function(source, cb, category) - MySQL.Async.fetchAll('SELECT * FROM fine_types WHERE category = @category', { - ['@category'] = category - }, function(fines) + MySQL.query('SELECT * FROM fine_types WHERE category = ?', {category}, + function(fines) cb(fines) end) end) ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, plate) - MySQL.Async.fetchAll('SELECT owner FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - local retrivedInfo = {plate = plate} - - if result[1] then - local xPlayer = ESX.GetPlayerFromIdentifier(result[1].owner) - - -- is the owner online? - if xPlayer then - retrivedInfo.owner = xPlayer.getName() - cb(retrivedInfo) - elseif Config.EnableESXIdentity then - MySQL.Async.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier', { - ['@identifier'] = result[1].owner - }, function(result2) - if result2[1] then - retrivedInfo.owner = ('%s %s'):format(result2[1].firstname, result2[1].lastname) - cb(retrivedInfo) - else - cb(retrivedInfo) - end - end) - else - cb(retrivedInfo) + local retrivedInfo = { + plate = plate + } + if Config.EnableESXIdentity then + MySQL.single('SELECT users.firstname, users.lastname FROM owned_vehicles JOIN users ON owned_vehicles.owner = users.identifier WHERE plate = ?', {plate}, + function(result) + if result then + retrivedInfo.owner = ('%s %s'):format(result.firstname, result.lastname) end - else cb(retrivedInfo) - end - end) + end) + else + MySQL.scalar('SELECT owner FROM owned_vehicles WHERE plate = ?', {plate}, + function(owner) + if owner then + local xPlayer = ESX.GetPlayerFromIdentifier(owner) + if xPlayer then + retrivedInfo.owner = xPlayer.getName() + end + end + cb(retrivedInfo) + end) + end end) ESX.RegisterServerCallback('esx_policejob:getArmoryWeapons', function(source, cb) @@ -278,7 +270,7 @@ ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, store.set('weapons', weapons) cb() - end) + end) end) ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, cb, weaponName) @@ -371,14 +363,8 @@ ESX.RegisterServerCallback('esx_policejob:buyJobVehicle', function(source, cb, v if xPlayer.getMoney() >= price then xPlayer.removeMoney(price) - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (@owner, @vehicle, @plate, @type, @job, @stored)', { - ['@owner'] = xPlayer.identifier, - ['@vehicle'] = json.encode(vehicleProps), - ['@plate'] = vehicleProps.plate, - ['@type'] = type, - ['@job'] = xPlayer.job.name, - ['@stored'] = true - }, function (rowsChanged) + MySQL.insert('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (?, ?, ?, ?, ?, ?)', { xPlayer.identifier, json.encode(vehicleProps), vehicleProps.plate, type, xPlayer.job.name, true}, + function (rowsChanged) cb(true) end) else @@ -387,47 +373,32 @@ ESX.RegisterServerCallback('esx_policejob:buyJobVehicle', function(source, cb, v end end) -ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, cb, nearbyVehicles) +ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, cb, plates) local xPlayer = ESX.GetPlayerFromId(source) - local foundPlate, foundNum - for k,v in ipairs(nearbyVehicles) do - local result = MySQL.Sync.fetchAll('SELECT plate FROM owned_vehicles WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = v.plate, - ['@job'] = xPlayer.job.name - }) + local plate = MySQL.scalar.await('SELECT plate FROM owned_vehicles WHERE owner = ? AND plate IN (?) AND job = ?', {xPlayer.identifier, plates, xPlayer.job.name}) - if result[1] then - foundPlate, foundNum = result[1].plate, k - break - end - end - - if not foundPlate then - cb(false) - else - MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = true WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = foundPlate, - ['@job'] = xPlayer.job.name - }, function (rowsChanged) + if plate then + MySQL.update('UPDATE owned_vehicles SET `stored` = true WHERE owner = ? AND plate = ? AND job = ?', {xPlayer.identifier, plate, xPlayer.job.name}, + function(rowsChanged) if rowsChanged == 0 then - print(('esx_policejob: %s has exploited the garage!'):format(xPlayer.identifier)) cb(false) else - cb(true, foundNum) + cb(plate) end end) + else + cb(false) end end) function getPriceFromHash(vehicleHash, jobGrade, type) local vehicles = Config.AuthorizedVehicles[type][jobGrade] - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == vehicleHash then - return v.price + for i = 1, #vehicles do + local vehicle = vehicles[i] + if GetHashKey(vehicle.model) == vehicleHash then + return vehicle.price end end diff --git a/[esx_addons]/esx_property/server/main.lua b/[esx_addons]/esx_property/server/main.lua index 3308cfa5..75d61881 100644 --- a/[esx_addons]/esx_property/server/main.lua +++ b/[esx_addons]/esx_property/server/main.lua @@ -7,7 +7,7 @@ function GetProperty(name) end function SetPropertyOwned(name, price, rented, owner) - MySQL.Async.execute('INSERT INTO owned_properties (name, price, rented, owner) VALUES (@name, @price, @rented, @owner)', { + MySQL.update('INSERT INTO owned_properties (name, price, rented, owner) VALUES (@name, @price, @rented, @owner)', { ['@name'] = name, ['@price'] = price, ['@rented'] = (rented and 1 or 0), @@ -28,12 +28,12 @@ function SetPropertyOwned(name, price, rented, owner) end function RemoveOwnedProperty(name, owner, noPay) - MySQL.Async.fetchAll('SELECT id, rented, price FROM owned_properties WHERE name = @name AND owner = @owner', { + MySQL.query('SELECT id, rented, price FROM owned_properties WHERE name = @name AND owner = @owner', { ['@name'] = name, ['@owner'] = owner }, function(result) if result[1] then - MySQL.Async.execute('DELETE FROM owned_properties WHERE id = @id', { + MySQL.update('DELETE FROM owned_properties WHERE id = @id', { ['@id'] = result[1].id }, function(rowsChanged) local xPlayer = ESX.GetPlayerFromIdentifier(owner) @@ -60,7 +60,7 @@ end MySQL.ready(function() Citizen.Wait(1500) - MySQL.Async.fetchAll('SELECT * FROM `properties`', {}, function(properties) + MySQL.query('SELECT * FROM `properties`', {}, function(properties) for i=1, #properties, 1 do local entering = nil @@ -136,7 +136,7 @@ ESX.RegisterServerCallback('esx_property:getProperties', function(source, cb) end) AddEventHandler('esx_ownedproperty:getOwnedProperties', function(cb) - MySQL.Async.fetchAll('SELECT * FROM owned_properties', {}, function(result) + MySQL.query('SELECT * FROM owned_properties', {}, function(result) local properties = {} for i=1, #result, 1 do @@ -198,7 +198,7 @@ RegisterNetEvent('esx_property:saveLastProperty') AddEventHandler('esx_property:saveLastProperty', function(property) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.execute('UPDATE users SET last_property = @last_property WHERE identifier = @identifier', { + MySQL.update('UPDATE users SET last_property = @last_property WHERE identifier = @identifier', { ['@last_property'] = property, ['@identifier'] = xPlayer.identifier }) @@ -208,7 +208,7 @@ RegisterNetEvent('esx_property:deleteLastProperty') AddEventHandler('esx_property:deleteLastProperty', function() local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.execute('UPDATE users SET last_property = NULL WHERE identifier = @identifier', { + MySQL.update('UPDATE users SET last_property = NULL WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }) end) @@ -315,7 +315,7 @@ end) ESX.RegisterServerCallback('esx_property:getOwnedProperties', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT name, rented FROM owned_properties WHERE owner = @owner', { + MySQL.query('SELECT name, rented FROM owned_properties WHERE owner = @owner', { ['@owner'] = xPlayer.identifier }, function(result) cb(result) @@ -325,7 +325,7 @@ end) ESX.RegisterServerCallback('esx_property:getLastProperty', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT last_property FROM users WHERE identifier = @identifier', { + MySQL.query('SELECT last_property FROM users WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }, function(users) cb(users[1].last_property) @@ -410,7 +410,7 @@ function payRent(d, h, m) local tasks, timeStart = {}, os.clock() print('[esx_property] [^2INFO^7] Paying rent cron job started') - MySQL.Async.fetchAll('SELECT * FROM owned_properties WHERE rented = 1', {}, function(result) + MySQL.query('SELECT * FROM owned_properties WHERE rented = 1', {}, function(result) for k,v in ipairs(result) do table.insert(tasks, function(cb) local xPlayer = ESX.GetPlayerFromIdentifier(v.owner) @@ -424,7 +424,7 @@ function payRent(d, h, m) RemoveOwnedProperty(v.name, v.owner, true) end else - MySQL.Async.fetchScalar('SELECT accounts FROM users WHERE identifier = @identifier', { + MySQL.scalar('SELECT accounts FROM users WHERE identifier = @identifier', { ['@identifier'] = v.owner }, function(accounts) if accounts then @@ -434,7 +434,7 @@ function payRent(d, h, m) if playerAccounts.bank >= v.price then playerAccounts.bank = playerAccounts.bank - v.price - MySQL.Async.execute('UPDATE users SET accounts = @accounts WHERE identifier = @identifier', { + MySQL.update('UPDATE users SET accounts = @accounts WHERE identifier = @identifier', { ['@identifier'] = v.owner, ['@accounts'] = json.encode(playerAccounts) }) diff --git a/[esx_addons]/esx_society/server/main.lua b/[esx_addons]/esx_society/server/main.lua index 0cab1a49..73704859 100644 --- a/[esx_addons]/esx_society/server/main.lua +++ b/[esx_addons]/esx_society/server/main.lua @@ -9,18 +9,20 @@ function GetSociety(name) end end -MySQL.ready(function() - local result = MySQL.Sync.fetchAll('SELECT * FROM jobs', {}) +AddEventHandler('onResourceStart', function(resourceName) + if resourceName == GetCurrentResourceName() then + local result = MySQL.query.await('SELECT * FROM jobs') - for i=1, #result, 1 do - Jobs[result[i].name] = result[i] - Jobs[result[i].name].grades = {} - end + for i = 1, #result, 1 do + Jobs[result[i].name] = result[i] + Jobs[result[i].name].grades = {} + end - local result2 = MySQL.Sync.fetchAll('SELECT * FROM job_grades', {}) + local result2 = MySQL.query.await('SELECT * FROM job_grades') - for i=1, #result2, 1 do - Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] + for i = 1, #result2, 1 do + Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] + end end end) @@ -108,11 +110,8 @@ AddEventHandler('esx_society:washMoney', function(society, amount) if amount and amount > 0 and account.money >= amount then xPlayer.removeAccountMoney('black_money', amount) - MySQL.Async.execute('INSERT INTO society_moneywash (identifier, society, amount) VALUES (@identifier, @society, @amount)', { - ['@identifier'] = xPlayer.identifier, - ['@society'] = society, - ['@amount'] = amount - }, function(rowsChanged) + MySQL.insert('INSERT INTO society_moneywash (identifier, society, amount) VALUES (?, ?, ?)', {xPlayer.identifier, society, amount}, + function(rowsChanged) xPlayer.showNotification(_U('you_have', ESX.Math.GroupDigits(amount))) end) else @@ -188,15 +187,14 @@ ESX.RegisterServerCallback('esx_society:getEmployees', function(source, cb, soci }) end - local query = "SELECT identifier, job_grade FROM `users` WHERE `job`=@job ORDER BY job_grade DESC" + local query = "SELECT identifier, job_grade FROM `users` WHERE `job`= ? ORDER BY job_grade DESC" if Config.EnableESXIdentity then - query = "SELECT identifier, job_grade, firstname, lastname FROM `users` WHERE `job`=@job ORDER BY job_grade DESC" + query = "SELECT identifier, job_grade, firstname, lastname FROM `users` WHERE `job`= ? ORDER BY job_grade DESC" end - MySQL.Async.fetchAll(query, { - ['@job'] = society - }, function(result) + MySQL.query(query, {society}, + function(result) for k, row in pairs(result) do local alreadyInTable local identifier = row.identifier @@ -270,11 +268,8 @@ ESX.RegisterServerCallback('esx_society:setJob', function(source, cb, identifier cb() else - MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade WHERE identifier = @identifier', { - ['@job'] = job, - ['@job_grade'] = grade, - ['@identifier'] = identifier - }, function(rowsChanged) + MySQL.update('UPDATE users SET job = ?, job_grade = ? WHERE identifier = ?', {job, grade, identifier}, + function(rowsChanged) cb() end) end @@ -289,11 +284,8 @@ ESX.RegisterServerCallback('esx_society:setJobSalary', function(source, cb, job, if xPlayer.job.name == job and xPlayer.job.grade_name == 'boss' then if salary <= Config.MaxSalary then - MySQL.Async.execute('UPDATE job_grades SET salary = @salary WHERE job_name = @job_name AND grade = @grade', { - ['@salary'] = salary, - ['@job_name'] = job, - ['@grade'] = grade - }, function(rowsChanged) + MySQL.update('UPDATE job_grades SET salary = ? WHERE job_name = ? AND grade = ?', {salary, job, grade}, + function(rowsChanged) Jobs[job].grades[tostring(grade)].salary = salary local xPlayers = ESX.GetExtendedPlayers('job', job) @@ -365,7 +357,7 @@ function isPlayerBoss(playerId, job) end function WashMoneyCRON(d, h, m) - MySQL.Async.fetchAll('SELECT * FROM society_moneywash', {}, function(result) + MySQL.query('SELECT * FROM society_moneywash', function(result) for i=1, #result, 1 do local society = GetSociety(result[i].society) local xPlayer = ESX.GetPlayerFromIdentifier(result[i].identifier) @@ -380,10 +372,8 @@ function WashMoneyCRON(d, h, m) xPlayer.showNotification(_U('you_have_laundered', ESX.Math.GroupDigits(result[i].amount))) end - MySQL.Async.execute('DELETE FROM society_moneywash WHERE id = @id', { - ['@id'] = result[i].id - }) end + MySQL.update('DELETE FROM society_moneywash') end) end diff --git a/[esx_addons]/esx_status/client/main.lua b/[esx_addons]/esx_status/client/main.lua index c29eca4d..20e3b2c5 100644 --- a/[esx_addons]/esx_status/client/main.lua +++ b/[esx_addons]/esx_status/client/main.lua @@ -65,12 +65,17 @@ AddEventHandler('esx_status:load', function(status) if Config.Display then TriggerEvent('esx_status:setDisplay', 0.5) end Citizen.CreateThread(function() + local data = {} while ESX.PlayerLoaded do - for i=1, #Status, 1 do + for i=1, #Status do Status[i].onTick() + table.insert(data, { + name = Status[i].name, + val = Status[i].val, + percent = (Status[i].val / 1000000) * 100 + }) end - local data = GetStatusData(true) - + if Config.Display then local fullData = data for i=1, #data, 1 do @@ -84,6 +89,7 @@ AddEventHandler('esx_status:load', function(status) end TriggerEvent('esx_status:onTick', data) + table.wipe(data) Citizen.Wait(Config.TickTime) end end) @@ -154,9 +160,9 @@ AddEventHandler('esx_status:setDisplay', function(val) end) -- Pause menu disable hud display -Citizen.CreateThread(function() - while true do - if Config.Display then +if Config.Display then + Citizen.CreateThread(function() + while true do Citizen.Wait(300) if IsPauseMenuActive() and not isPaused then @@ -166,9 +172,9 @@ Citizen.CreateThread(function() isPaused = false TriggerEvent('esx_status:setDisplay', 0.5) end - else Citizen.Wait(1000) end - end -end) + end + end) +end -- Loading screen off event AddEventHandler('esx:loadingScreenOff', function() diff --git a/[esx_addons]/esx_status/fxmanifest.lua b/[esx_addons]/esx_status/fxmanifest.lua index ac962a5c..4955a0b6 100644 --- a/[esx_addons]/esx_status/fxmanifest.lua +++ b/[esx_addons]/esx_status/fxmanifest.lua @@ -6,6 +6,8 @@ description 'ESX Status' version 'legacy' +lua54 'yes' + shared_script '@es_extended/imports.lua' server_scripts { @@ -27,3 +29,5 @@ files { 'html/css/app.css', 'html/scripts/app.js' } + +dependency 'es_extended' diff --git a/[esx_addons]/esx_status/server/main.lua b/[esx_addons]/esx_status/server/main.lua index a0b436ef..a4f6b1a2 100644 --- a/[esx_addons]/esx_status/server/main.lua +++ b/[esx_addons]/esx_status/server/main.lua @@ -1,43 +1,26 @@ +local function setPlayerStatus(xPlayer, data) + data = data and json.decode(data) or {} + + xPlayer.set('status', data) + ESX.Players[xPlayer.source] = data + TriggerClientEvent('esx_status:load', xPlayer.source, data) +end + AddEventHandler('onResourceStart', function(resourceName) if (GetCurrentResourceName() ~= resourceName) then return end - + for _, xPlayer in pairs(ESX.Players) do - local status = xPlayer.get('status') - if status then - ESX.Players[xPlayer.source] = status - else - MySQL.Async.fetchAll('SELECT status FROM users WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) - local data = {} - - if result[1].status then - data = json.decode(result[1].status) - end - - xPlayer.set('status', data) -- save to xPlayer for compatibility - ESX.Players[xPlayer.source] = data -- save locally for performance - end) - end - TriggerClientEvent('esx_status:load', xPlayer.source, data) + MySQL.scalar('SELECT status FROM users WHERE identifier = ?', { xPlayer.identifier }, function(result) + setPlayerStatus(xPlayer, result) + end) end end) AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - MySQL.Async.fetchAll('SELECT status FROM users WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) - local data = {} - - if result[1].status then - data = json.decode(result[1].status) - end - - xPlayer.set('status', data) - ESX.Players[xPlayer.source] = data - TriggerClientEvent('esx_status:load', playerId, data) + MySQL.scalar('SELECT status FROM users WHERE identifier = ?', { xPlayer.identifier }, function(result) + setPlayerStatus(xPlayer, result) end) end) @@ -45,19 +28,15 @@ AddEventHandler('esx:playerDropped', function(playerId, reason) local xPlayer = ESX.GetPlayerFromId(playerId) local status = ESX.Players[xPlayer.source] - MySQL.Async.execute('UPDATE users SET status = @status WHERE identifier = @identifier', { - ['@status'] = json.encode(status), - ['@identifier'] = xPlayer.identifier - }, function(result) - ESX.Players[xPlayer.source] = nil - end) + MySQL.update('UPDATE users SET status = ? WHERE identifier = ?', { json.encode(status), xPlayer.identifier }) + ESX.Players[xPlayer.source] = nil end) AddEventHandler('esx_status:getStatus', function(playerId, statusName, cb) - for i=1, #ESX.Players, 1 do + local status = ESX.Players[playerId] + for i = 1, #status do if status[i].name == statusName then - cb(status[i]) - break + return cb(status[i]) end end end) @@ -72,50 +51,17 @@ AddEventHandler('esx_status:update', function(status) end) Citizen.CreateThread(function() - while(true) do + while true do Citizen.Wait(10 * 60 * 1000) - SaveData() - end -end) - -function SaveData() - -- Example of a bulk update statement that we are building below - --[[ - UPDATE users - SET status = (case when identifier = 'license:123' then '{hunger:45, thirst:23}' - when identifier = 'license:456' then '{hunger:1000, thirst:1000}' - when identifier = 'license:789' then '{hunger:1000, thirst:1000}' - end) - WHERE identifier in ('license:123', 'license:456', 'license:789') - - ]] - local updateStatement = 'UPDATE users SET status = (case %s end) where identifier in (%s)' - local whenList = '' - local whereList = '' - local firstItem = true - local playerCount = 0 - - local xPlayers = ESX.GetExtendedPlayers() - - for _, xPlayer in pairs(xPlayers) do - local status = ESX.Players[xPlayer.source] - if status then - whenList = whenList .. string.format('when identifier = \'%s\' then \'%s\' ', xPlayer.identifier, json.encode(status)) - - if firstItem == false then - whereList = whereList .. ', ' + local parameters = {} + for _, xPlayer in pairs(ESX.GetExtendedPlayers()) do + local status = ESX.Players[xPlayer.source] + if status and next(status) then + parameters[#parameters+1] = {json.encode(status), xPlayer.identifier} end - whereList = whereList .. string.format('\'%s\'', xPlayer.identifier) - - firstItem = false - playerCount = playerCount + 1 + end + if #parameters > 0 then + MySQL.prepare('UPDATE users SET status = ? WHERE identifier = ?', parameters) end end - - if playerCount > 0 then - local sql = string.format(updateStatement, whenList, whereList) - MySQL.Async.execute(sql) - - end - -end +end) diff --git a/[esx_addons]/esx_vehicleshop/client/main.lua b/[esx_addons]/esx_vehicleshop/client/main.lua index db7c6264..8435b328 100644 --- a/[esx_addons]/esx_vehicleshop/client/main.lua +++ b/[esx_addons]/esx_vehicleshop/client/main.lua @@ -2,10 +2,11 @@ local HasAlreadyEnteredMarker, IsInShopMenu = false, false local CurrentAction, CurrentActionMsg, LastZone, currentDisplayVehicle, CurrentVehicleData local CurrentActionData, Vehicles, Categories = {}, {}, {} -function getVehicleLabelFromModel(model) - for k,v in ipairs(Vehicles) do - if v.model == model then - return v.name +function getVehicleFromModel(model) + for i = 1, #Vehicles do + local vehicle = Vehicles[i] + if vehicle.model == model then + return vehicle end end @@ -82,7 +83,7 @@ function ReturnVehicleProvider() for k,v in ipairs(vehicles) do local returnPrice = ESX.Math.Round(v.price * 0.75) - local vehicleLabel = getVehicleLabelFromModel(v.vehicle) + local vehicleLabel = getVehicleFromModel(v.vehicle).label table.insert(elements, { label = ('%s [%s]'):format(vehicleLabel, _U('generic_shopitem', ESX.Math.GroupDigits(returnPrice))), @@ -143,7 +144,7 @@ function OpenShopMenu() end for i=1, #Vehicles, 1 do - if IsModelInCdimage(GetHashKey(Vehicles[i].model)) then + if IsModelInCdimage(joaat(Vehicles[i].model)) then table.insert(vehiclesByCategory[Vehicles[i].category], Vehicles[i]) else print(('[esx_vehicleshop] [^3ERROR^7] Vehicle "%s" does not exist'):format(Vehicles[i].model)) @@ -289,7 +290,7 @@ function OpenShopMenu() end function WaitForVehicleToLoad(modelHash) - modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) + modelHash = (type(modelHash) == 'number' and modelHash or joaat(modelHash)) if not HasModelLoaded(modelHash) then RequestModel(modelHash) diff --git a/[esx_addons]/esx_vehicleshop/client/utils.lua b/[esx_addons]/esx_vehicleshop/client/utils.lua index 88a30d50..277f2ecf 100644 --- a/[esx_addons]/esx_vehicleshop/client/utils.lua +++ b/[esx_addons]/esx_vehicleshop/client/utils.lua @@ -50,7 +50,6 @@ end function GetRandomNumber(length) Citizen.Wait(0) - math.randomseed(GetGameTimer()) if length > 0 then return GetRandomNumber(length - 1) .. NumberCharset[math.random(1, #NumberCharset)] else @@ -60,7 +59,6 @@ end function GetRandomLetter(length) Citizen.Wait(0) - math.randomseed(GetGameTimer()) if length > 0 then return GetRandomLetter(length - 1) .. Charset[math.random(1, #Charset)] else diff --git a/[esx_addons]/esx_vehicleshop/fxmanifest.lua b/[esx_addons]/esx_vehicleshop/fxmanifest.lua index 0fbc8c70..884cca1d 100644 --- a/[esx_addons]/esx_vehicleshop/fxmanifest.lua +++ b/[esx_addons]/esx_vehicleshop/fxmanifest.lua @@ -2,6 +2,8 @@ fx_version 'adamant' game 'gta5' +lua54 'yes' + description 'ESX Vehicle Shop' version 'legacy' diff --git a/[esx_addons]/esx_vehicleshop/server/main.lua b/[esx_addons]/esx_vehicleshop/server/main.lua index 78622caa..fc675937 100644 --- a/[esx_addons]/esx_vehicleshop/server/main.lua +++ b/[esx_addons]/esx_vehicleshop/server/main.lua @@ -14,35 +14,29 @@ Citizen.CreateThread(function() end) function RemoveOwnedVehicle(plate) - MySQL.Async.execute('DELETE FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }) + MySQL.update('DELETE FROM owned_vehicles WHERE plate = ?', {plate}) end AddEventHandler('onResourceStart', function(resourceName) - if resourceName == GetCurrentResourceName() then - MySQL.ready(function() SQLVehiclesAndCategories() end) - end + if resourceName == GetCurrentResourceName() then + SQLVehiclesAndCategories() + end end) function SQLVehiclesAndCategories() - MySQL.Async.fetchAll('SELECT * FROM `vehicle_categories`', {}, function(_categories) - categories = _categories + categories = MySQL.query.await('SELECT * FROM vehicle_categories') + vehicles = MySQL.query.await('SELECT * FROM vehicles') - MySQL.Async.fetchAll('SELECT * FROM `vehicles`', {}, function(_vehicles) - vehicles = _vehicles - - GetVehiclesAndCategories(categories, vehicles) - end) - - end) + GetVehiclesAndCategories(categories, vehicles) end function GetVehiclesAndCategories(categories, vehicles) - for k,v in ipairs(vehicles) do - for k2,v2 in ipairs(categories) do - if v2.name == v.category then - vehicles[k].categoryLabel = v2.label + for i = 1, #vehicles do + local vehicle = vehicles[i] + for j = 1, #categories do + local category = categories[j] + if category.name == vehicle.catetgory then + vehicle.categoryLabel = category.label break end end @@ -53,10 +47,11 @@ function GetVehiclesAndCategories(categories, vehicles) TriggerClientEvent('esx_vehicleshop:sendVehicles', -1, vehicles) end -function getVehicleLabelFromModel(model) - for k,v in ipairs(vehicles) do - if v.model == model then - return v.name +function getVehicleFromModel(model) + for i = 1, #vehicles do + local vehicle = vehicles[i] + if vehicle.model == model then + return vehicle end end @@ -68,34 +63,19 @@ AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, ve local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) if xPlayer.job.name == 'cardealer' and xTarget then - MySQL.Async.fetchAll('SELECT id FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = model - }, function(result) - if result[1] then - local id = result[1].id - - MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) + MySQL.scalar('SELECT id FROM cardealer_vehicles WHERE vehicle = ?', {model}, + function(id) + if id then + MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {id}, + function(rowsChanged) if rowsChanged == 1 then - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', { - ['@owner'] = xTarget.identifier, - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps) - }, function(rowsChanged) + MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {xTarget.identifier, vehicleProps.plate, json.encode(vehicleProps)}, + function(id) xPlayer.showNotification(_U('vehicle_set_owned', vehicleProps.plate, xTarget.getName())) xTarget.showNotification(_U('vehicle_belongs', vehicleProps.plate)) end) - local dateNow = os.date('%Y-%m-%d %H:%M') - - MySQL.Async.execute('INSERT INTO vehicle_sold (client, model, plate, soldby, date) VALUES (@client, @model, @plate, @soldby, @date)', { - ['@client'] = xTarget.getName(), - ['@model'] = label, - ['@plate'] = vehicleProps.plate, - ['@soldby'] = xPlayer.getName(), - ['@date'] = dateNow - }) + MySQL.insert('INSERT INTO vehicle_sold (client, model, plate, soldby, date) VALUES (?, ?, ?, ?, ?)', {xTarget.getName(), label, vehicleProps.plate, xPlayer.getName(), os.date('%Y-%m-%d %H:%M')}) end end) end @@ -104,7 +84,7 @@ AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, ve end) ESX.RegisterServerCallback('esx_vehicleshop:getSoldVehicles', function(source, cb) - MySQL.Async.fetchAll('SELECT client, model, plate, soldby, date FROM vehicle_sold', {}, function(result) + MySQL.query('SELECT client, model, plate, soldby, date FROM vehicle_sold', function(result) cb(result) end) end) @@ -114,24 +94,14 @@ AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, rentPric local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) if xPlayer.job.name == 'cardealer' and xTarget then - MySQL.Async.fetchAll('SELECT id, price FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = vehicle - }, function(result) - if result[1] then - local price = result[1].price - - MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = result[1].id - }, function(rowsChanged) + MySQL.single('SELECT id, price FROM cardealer_vehicles WHERE vehicle = ?', {vehicle}, + function(result) + if result then + MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {result.id}, + function(rowsChanged) if rowsChanged == 1 then - MySQL.Async.execute('INSERT INTO rented_vehicles (vehicle, plate, player_name, base_price, rent_price, owner) VALUES (@vehicle, @plate, @player_name, @base_price, @rent_price, @owner)', { - ['@vehicle'] = vehicle, - ['@plate'] = plate, - ['@player_name'] = xTarget.getName(), - ['@base_price'] = price, - ['@rent_price'] = rentPrice, - ['@owner'] = xTarget.identifier - }, function(rowsChanged2) + MySQL.insert('INSERT INTO rented_vehicles (vehicle, plate, player_name, base_price, rent_price, owner) VALUES (?, ?, ?, ?, ?, ?)', {vehicle, plate, xTarget.getName(), result.price, rentPrice, xTarget.identifier}, + function(id) xPlayer.showNotification(_U('vehicle_set_rented', plate, xTarget.getName())) end) end @@ -194,22 +164,12 @@ end) ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, model, plate) local xPlayer = ESX.GetPlayerFromId(source) - local modelPrice - - for k,v in ipairs(vehicles) do - if model == v.model then - modelPrice = v.price - break - end - end + local modelPrice = getVehicleFromModel(model).price if modelPrice and xPlayer.getMoney() >= modelPrice then xPlayer.removeMoney(modelPrice) - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = plate, - ['@vehicle'] = json.encode({model = GetHashKey(model), plate = plate}) + MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {xPlayer.identifier, plate, json.encode({model = joaat(model), plate = plate}) }, function(rowsChanged) xPlayer.showNotification(_U('vehicle_belongs', plate)) cb(true) @@ -220,7 +180,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, mo end) ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function(source, cb) - MySQL.Async.fetchAll('SELECT price, vehicle FROM cardealer_vehicles ORDER BY vehicle ASC', {}, function(result) + MySQL.query('SELECT price, vehicle FROM cardealer_vehicles ORDER BY vehicle ASC', function(result) cb(result) end) end) @@ -229,24 +189,15 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyCarDealerVehicle', function(sourc local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.job.name == 'cardealer' then - local modelPrice - - for k,v in ipairs(vehicles) do - if model == v.model then - modelPrice = v.price - break - end - end + local modelPrice = getVehicleFromModel(model).price if modelPrice then TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) if account.money >= modelPrice then account.removeMoney(modelPrice) - MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { - ['@vehicle'] = model, - ['@price'] = modelPrice - }, function(rowsChanged) + MySQL.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {model, modelPrice}, + function(rowsChanged) cb(true) end) else @@ -262,19 +213,17 @@ AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.job.name == 'cardealer' then - MySQL.Async.fetchAll('SELECT id, price FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = vehicleModel - }, function(result) - if result[1] then - local id = result[1].id + MySQL.single('SELECT id, price FROM cardealer_vehicles WHERE vehicle = ?', {vehicleModel}, + function(result) + if result then + local id = result.id - MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) + MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {id}, + function(rowsChanged) if rowsChanged == 1 then TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) - local price = ESX.Math.Round(result[1].price * 0.75) - local vehicleLabel = getVehicleLabelFromModel(vehicleModel) + local price = ESX.Math.Round(result.price * 0.75) + local vehicleLabel = getVehicleFromModel(vehicleModel).label account.addMoney(price) xPlayer.showNotification(_U('vehicle_sold_for', vehicleLabel, ESX.Math.GroupDigits(price))) @@ -289,15 +238,16 @@ AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) end) ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, cb) - MySQL.Async.fetchAll('SELECT * FROM rented_vehicles ORDER BY player_name ASC', {}, function(result) + MySQL.query('SELECT * FROM rented_vehicles ORDER BY player_name ASC', function(result) local vehicles = {} - for i=1, #result, 1 do - table.insert(vehicles, { - name = result[i].vehicle, - plate = result[i].plate, - playerName = result[i].player_name - }) + for i = 1, #result do + local vehicle = tab[i] + vehicles[#vehicles + 1] = { + name = vehicle.vehicle, + plate = vehicle.plate, + playerName = vehicle.player_name + } end cb(vehicles) @@ -305,20 +255,15 @@ ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, end) ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, cb, plate) - MySQL.Async.fetchAll('SELECT base_price, vehicle FROM rented_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - if result[1] then - local vehicle = result[1].vehicle - local basePrice = result[1].base_price + MySQL.single('SELECT base_price, vehicle FROM rented_vehicles WHERE plate = ?', {plate}, + function(result) + if result then + local vehicle = result.vehicle + local basePrice = result.base_price - MySQL.Async.execute('DELETE FROM rented_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(rowsChanged) - MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { - ['@vehicle'] = vehicle, - ['@price'] = basePrice - }) + MySQL.update('DELETE FROM rented_vehicles WHERE plate = ?', {plate}, + function(rowsChanged) + MySQL.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {result.vehicle, result.base_price}) RemoveOwnedVehicle(plate) cb(true) @@ -335,7 +280,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, if xPlayer.job.name == 'cardealer' or not Config.EnablePlayerManagement then -- calculate the resell price for i=1, #vehicles, 1 do - if GetHashKey(vehicles[i].model) == model then + if joaat(vehicles[i].model) == model then resellPrice = ESX.Math.Round(vehicles[i].price / 100 * Config.ResellPercentage) break end @@ -345,18 +290,15 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an unknown vehicle!'):format(xPlayer.identifier)) cb(false) else - MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - if result[1] then -- is it a rented vehicle? + MySQL.single('SELECT * FROM rented_vehicles WHERE plate = ?', {plate}, + function(result) + if result then -- is it a rented vehicle? cb(false) -- it is, don't let the player sell it since he doesn't own it else - MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = plate - }, function(result) - if result[1] then -- does the owner match? - local vehicle = json.decode(result[1].vehicle) + MySQL.single('SELECT * FROM owned_vehicles WHERE owner = ? AND plate = ?', {xPlayer.identifier, plate}, + function(result) + if result then -- does the owner match? + local vehicle = json.decode(result.vehicle) if vehicle.model == model then if vehicle.plate == plate then @@ -393,21 +335,17 @@ ESX.RegisterServerCallback('esx_vehicleshop:getPlayerInventory', function(source end) ESX.RegisterServerCallback('esx_vehicleshop:isPlateTaken', function(source, cb, plate) - MySQL.Async.fetchAll('SELECT 1 FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - cb(result[1] ~= nil) + MySQL.scalar('SELECT plate FROM owned_vehicles WHERE plate = ?', {plate}, + function(result) + cb(result ~= nil) end) end) ESX.RegisterServerCallback('esx_vehicleshop:retrieveJobVehicles', function(source, cb, type) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND type = @type AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@type'] = type, - ['@job'] = xPlayer.job.name - }, function(result) + MySQL.query('SELECT * FROM owned_vehicles WHERE owner = ? AND type = ? AND job = ?', {xPlayer.identifier, type, xPlayer.job.name}, + function(result) cb(result) end) end) @@ -416,76 +354,101 @@ RegisterNetEvent('esx_vehicleshop:setJobVehicleState') AddEventHandler('esx_vehicleshop:setJobVehicleState', function(plate, state) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = @stored WHERE plate = @plate AND job = @job', { - ['@stored'] = state, - ['@plate'] = plate, - ['@job'] = xPlayer.job.name - }, function(rowsChanged) + MySQL.update('UPDATE owned_vehicles SET `stored` = ? WHERE plate = ? AND job = ?', {state, plate, xPlayer.job.name}, + function(rowsChanged) if rowsChanged == 0 then print(('[esx_vehicleshop] [^3WARNING^7] %s exploited the garage!'):format(xPlayer.identifier)) end end) end) -function UnrentVehicleAsync(identifier, plate) - MySQL.Async.execute('DELETE FROM rented_vehicles WHERE identifier = @identifier AND plate = @plate', { - ['@identifier'] = identifier, - ['@plate'] = plate - }) -end - -function PayRent(d, h, m) - local tasks, timeStart = {}, os.clock() +function PayRent() + local timeStart = os.clock() print('[esx_vehicleshop] [^2INFO^7] Paying rent cron job started') - MySQL.Async.fetchAll('SELECT owner, rent_price, plate FROM rented_vehicles', {}, function(result) - for k,v in ipairs(result) do - table.insert(tasks, function(cb) - local xPlayer = ESX.GetPlayerFromIdentifier(v.owner) + MySQL.query('SELECT rented_vehicles.owner, rented_vehicles.rent_price, rented_vehicles.plate, users.accounts FROM rented_vehicles LEFT JOIN users ON rented_vehicles.owner = users.identifier', {}, + function(rentals) + local owners = {} + for i = 1, #rentals do + local rental = rentals[i] + if not owners[rental.owner] then + owners[rental.owner] = {rental} + else + owners[rental.owner][#owners[rental.owner] + 1] = rental + end + end - if xPlayer then - if xPlayer.getAccount('bank').money >= v.rent_price then - xPlayer.removeAccountMoney('bank', v.rent_price) - xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(v.rent_price), v.plate)) - else - xPlayer.showNotification(_U('paid_rental_evicted', ESX.Math.GroupDigits(v.rent_price), v.plate)) - UnrentVehicleAsync(v.owner, v.plate) - end + local total = 0 + local unrentals = {} + local users = {} + for k, v in pairs(owners) do + local sum = 0 + for i = 1, #v do + sum += v[i].rent_price + end + local xPlayer = ESX.GetPlayerFromIdentifier(k) + + if xPlayer then + local bank = xPlayer.getAccount('bank').money + + if bank >= sum and #v > 1 then + total += sum + xPlayer.removeAccountMoney('bank', sum) + xPlayer.showNotification(('You have paid ~g~$%s~s~ for all of your rentals'):format(ESX.Math.GroupDigits(sum))) else - MySQL.Async.fetchScalar('SELECT accounts FROM users WHERE identifier = @identifier', { - ['@identifier'] = v.owner - }, function(accounts) - if accounts then - local playerAccounts = json.decode(accounts) - - if playerAccounts and playerAccounts.bank then - if playerAccounts.bank >= v.price then - playerAccounts.bank = playerAccounts.bank - v.price - - MySQL.Async.execute('UPDATE users SET accounts = @accounts WHERE identifier = @identifier', { - ['@identifier'] = v.owner, - ['@accounts'] = json.encode(playerAccounts) - }) - else - UnrentVehicleAsync(v.owner, v.plate) - end - end + for i = 1, #v do + local rental = v[i] + if xPlayer.getAccount('bank').money >= rental.rent_price then + total += rental.rent_price + xPlayer.removeAccountMoney('bank', rental.rent_price) + xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(rental.rent_price), rental.plate)) + else + xPlayer.showNotification(_U('paid_rental_evicted', ESX.Math.GroupDigits(rental.rent_price), rental.plate)) + unrentals[#unrentals + 1] = {rental.owner, rental.plate} end - end) + end end + else + local accounts = json.decode(v[1].accounts) + if accounts.bank < sum then + sum = 0 + local limit = false + for i = 1, #v do + local rental = v[i] + if not limit then + sum += rental.rent_price + if sum > accounts.bank then + sum -= rental.rent_price + limit = true + end + else + unrentals[#unrentals + 1] = {rental.owner, rental.plate} + end + end + end + if sum > 0 then + total += sum + accounts.bank -= sum + users[#users + 1] = {json.encode(accounts), k} + end + end + end - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) - account.addMoney(result[i].rent_price) - end) - - cb() + if total > 0 then + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + account.addMoney(total) end) end - Async.parallelLimit(tasks, 5, function(results) end) + if next(users) then + MySQL.prepare.await('UPDATE users SET accounts = ? WHERE identifier = ?', users) + end - local elapsedTime = os.clock() - timeStart - print(('[esx_vehicleshop] [^2INFO^7] Paying rent cron job took %s seconds'):format(elapsedTime)) + if next(unrentals) then + MySQL.prepare.await('DELETE FROM rented_vehicles WHERE owner = ? AND plate = ?', unrentals) + end + + print(('[esx_vehicleshop] [^2INFO^7] Paying rent cron job took %s seconds'):format(os.clock() - timeStart)) end) end diff --git a/[esx_addons]/esx_weaponshop/server/main.lua b/[esx_addons]/esx_weaponshop/server/main.lua index 8d9a4ac3..26d58463 100644 --- a/[esx_addons]/esx_weaponshop/server/main.lua +++ b/[esx_addons]/esx_weaponshop/server/main.lua @@ -2,7 +2,7 @@ local shopItems = {} MySQL.ready(function() - MySQL.Async.fetchAll('SELECT * FROM weashops', {}, function(result) + MySQL.query('SELECT * FROM weashops', {}, function(result) for i=1, #result, 1 do if shopItems[result[i].zone] == nil then shopItems[result[i].zone] = {} @@ -77,7 +77,7 @@ ESX.RegisterServerCallback('esx_weaponshop:buyWeapon', function(source, cb, weap end) function GetPrice(weaponName, zone) - local price = MySQL.Sync.fetchScalar('SELECT price FROM weashops WHERE zone = @zone AND item = @item', { + local price = MySQL.scalar.await('SELECT price FROM weashops WHERE zone = @zone AND item = @item', { ['@zone'] = zone, ['@item'] = weaponName }) diff --git a/[esx_addons]/esx_whitelist/server/commands.lua b/[esx_addons]/esx_whitelist/server/commands.lua index 70bfd3e0..e9d8193e 100644 --- a/[esx_addons]/esx_whitelist/server/commands.lua +++ b/[esx_addons]/esx_whitelist/server/commands.lua @@ -11,7 +11,7 @@ ESX.RegisterCommand('wladd', 'admin', function(xPlayer, args, showError) if WhiteList[args.license] then showError('The player is already whitelisted on this server!') else - MySQL.Async.execute('INSERT INTO whitelist (identifier) VALUES (@identifier)', { + MySQL.update('INSERT INTO whitelist (identifier) VALUES (@identifier)', { ['@identifier'] = args.license }, function(rowsChanged) WhiteList[args.license] = true diff --git a/[esx_addons]/esx_whitelist/server/main.lua b/[esx_addons]/esx_whitelist/server/main.lua index e82b6483..10af6543 100644 --- a/[esx_addons]/esx_whitelist/server/main.lua +++ b/[esx_addons]/esx_whitelist/server/main.lua @@ -3,7 +3,7 @@ WhiteList = {} function loadWhiteList(cb) Whitelist = {} - MySQL.Async.fetchAll('SELECT identifier FROM whitelist', {}, function(result) + MySQL.query('SELECT identifier FROM whitelist', {}, function(result) for k,v in ipairs(result) do WhiteList[v.identifier] = true end diff --git a/database.sql b/database.sql new file mode 100644 index 00000000..5665cb79 --- /dev/null +++ b/database.sql @@ -0,0 +1,1041 @@ +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + + +-- Dumping database structure for es_extended +CREATE DATABASE IF NOT EXISTS `es_extended` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */; +USE `es_extended`; + +-- Dumping structure for table es_extended.accounts +CREATE TABLE IF NOT EXISTS `accounts` ( + `name` varchar(255) NOT NULL, + `owner` varchar(64) DEFAULT NULL, + `money` int(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.accounts: ~0 rows (approximately) +/*!40000 ALTER TABLE `accounts` DISABLE KEYS */; +/*!40000 ALTER TABLE `accounts` ENABLE KEYS */; + +-- Dumping structure for table es_extended.addon_account +CREATE TABLE IF NOT EXISTS `addon_account` ( + `name` varchar(60) NOT NULL, + `label` varchar(100) NOT NULL, + `shared` int(11) NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.addon_account: ~10 rows (approximately) +/*!40000 ALTER TABLE `addon_account` DISABLE KEYS */; +INSERT INTO `addon_account` (`name`, `label`, `shared`) VALUES + ('bank_savings', 'Bank Savings', 0), + ('caution', 'caution', 0), + ('property_black_money', 'Dirty Money Property', 0), + ('society_ambulance', 'EMS', 1), + ('society_banker', 'Banker', 1), + ('society_cardealer', 'Cardealer', 1), + ('society_mechanic', 'Mechanic', 1), + ('society_police', 'Police', 1), + ('society_realestateagent', 'Real Estate Company', 1), + ('society_taxi', 'Taxi', 1); +/*!40000 ALTER TABLE `addon_account` ENABLE KEYS */; + +-- Dumping structure for table es_extended.addon_account_data +CREATE TABLE IF NOT EXISTS `addon_account_data` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `account_name` varchar(100) DEFAULT NULL, + `money` int(11) NOT NULL, + `owner` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_addon_account_data_account_name_owner` (`account_name`,`owner`), + KEY `index_addon_account_data_account_name` (`account_name`) +) ENGINE=InnoDB AUTO_INCREMENT=11; + +-- Dumping data for table es_extended.addon_account_data: ~10 rows (approximately) +/*!40000 ALTER TABLE `addon_account_data` DISABLE KEYS */; +INSERT INTO `addon_account_data` (`id`, `account_name`, `money`, `owner`) VALUES + (1, 'society_cardealer', 0, NULL), + (2, 'society_police', 0, NULL), + (3, 'society_ambulance', 0, NULL), + (4, 'society_mechanic', 0, NULL), + (5, 'society_taxi', 0, NULL), + (6, 'society_realestateagent', 0, NULL), + (7, 'society_banker', 0, NULL); +/*!40000 ALTER TABLE `addon_account_data` ENABLE KEYS */; + +-- Dumping structure for table es_extended.addon_inventory +CREATE TABLE IF NOT EXISTS `addon_inventory` ( + `name` varchar(60) NOT NULL, + `label` varchar(100) NOT NULL, + `shared` int(11) NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.addon_inventory: ~7 rows (approximately) +/*!40000 ALTER TABLE `addon_inventory` DISABLE KEYS */; +INSERT INTO `addon_inventory` (`name`, `label`, `shared`) VALUES + ('property', 'Property', 0), + ('society_ambulance', 'EMS', 1), + ('society_cardealer', 'Cardealer', 1), + ('society_mechanic', 'Mechanic', 1), + ('society_police', 'Police', 1), + ('society_realestateagent', 'Real Estate Company', 1), + ('society_taxi', 'Taxi', 1); +/*!40000 ALTER TABLE `addon_inventory` ENABLE KEYS */; + +-- Dumping structure for table es_extended.addon_inventory_items +CREATE TABLE IF NOT EXISTS `addon_inventory_items` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `inventory_name` varchar(100) NOT NULL, + `name` varchar(100) NOT NULL, + `count` int(11) NOT NULL, + `owner` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `index_addon_inventory_items_inventory_name_name` (`inventory_name`,`name`), + KEY `index_addon_inventory_items_inventory_name_name_owner` (`inventory_name`,`name`,`owner`), + KEY `index_addon_inventory_inventory_name` (`inventory_name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.addon_inventory_items: ~0 rows (approximately) +/*!40000 ALTER TABLE `addon_inventory_items` DISABLE KEYS */; +/*!40000 ALTER TABLE `addon_inventory_items` ENABLE KEYS */; + +-- Dumping structure for table es_extended.billing +CREATE TABLE IF NOT EXISTS `billing` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(60) NOT NULL, + `sender` varchar(60) NOT NULL, + `target_type` varchar(50) NOT NULL, + `target` varchar(60) NOT NULL, + `label` varchar(255) NOT NULL, + `amount` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `identifier` (`identifier`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.billing: ~0 rows (approximately) +/*!40000 ALTER TABLE `billing` DISABLE KEYS */; +/*!40000 ALTER TABLE `billing` ENABLE KEYS */; + +-- Dumping structure for table es_extended.cardealer_vehicles +CREATE TABLE IF NOT EXISTS `cardealer_vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.cardealer_vehicles: ~0 rows (approximately) +/*!40000 ALTER TABLE `cardealer_vehicles` DISABLE KEYS */; +/*!40000 ALTER TABLE `cardealer_vehicles` ENABLE KEYS */; + +-- Dumping structure for table es_extended.datastore +CREATE TABLE IF NOT EXISTS `datastore` ( + `name` varchar(60) NOT NULL, + `label` varchar(100) NOT NULL, + `shared` int(11) NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.datastore: ~10 rows (approximately) +/*!40000 ALTER TABLE `datastore` DISABLE KEYS */; +INSERT INTO `datastore` (`name`, `label`, `shared`) VALUES + ('property', 'Property', 0), + ('society_ambulance', 'EMS', 1), + ('society_mechanic', 'Mechanic', 1), + ('society_police', 'Police', 1), + ('society_realestateagent', 'Taxi', 1), + ('society_taxi', 'Real Estate Company', 1), + ('user_ears', 'Ears', 0), + ('user_glasses', 'Glasses', 0), + ('user_helmet', 'Helmet', 0), + ('user_mask', 'Mask', 0); +/*!40000 ALTER TABLE `datastore` ENABLE KEYS */; + +-- Dumping structure for table es_extended.datastores +CREATE TABLE IF NOT EXISTS `datastores` ( + `name` varchar(255) NOT NULL, + `owner` varchar(64) DEFAULT NULL, + `data` longtext DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `owner` (`owner`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.datastores: ~0 rows (approximately) +/*!40000 ALTER TABLE `datastores` DISABLE KEYS */; +/*!40000 ALTER TABLE `datastores` ENABLE KEYS */; + +-- Dumping structure for table es_extended.datastore_data +CREATE TABLE IF NOT EXISTS `datastore_data` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `owner` varchar(60) DEFAULT NULL, + `data` longtext DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_datastore_data_name_owner` (`name`,`owner`), + KEY `index_datastore_data_name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=11; + +-- Dumping data for table es_extended.datastore_data: ~10 rows (approximately) +/*!40000 ALTER TABLE `datastore_data` DISABLE KEYS */; +INSERT INTO `datastore_data` (`id`, `name`, `owner`, `data`) VALUES + (1, 'society_police', NULL, '{}'), + (2, 'society_ambulance', NULL, '{}'), + (3, 'society_mechanic', NULL, '{}'), + (4, 'society_taxi', NULL, '{}'), + (5, 'society_realestateagent', NULL, '{}'); +/*!40000 ALTER TABLE `datastore_data` ENABLE KEYS */; + +-- Dumping structure for table es_extended.fine_types +CREATE TABLE IF NOT EXISTS `fine_types` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `label` varchar(255) DEFAULT NULL, + `amount` int(11) DEFAULT NULL, + `category` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=105; + +-- Dumping data for table es_extended.fine_types: ~52 rows (approximately) +/*!40000 ALTER TABLE `fine_types` DISABLE KEYS */; +INSERT INTO `fine_types` (`id`, `label`, `amount`, `category`) VALUES + (53, 'Misuse of a horn', 30, 0), + (54, 'Illegally Crossing a continuous Line', 40, 0), + (55, 'Driving on the wrong side of the road', 250, 0), + (56, 'Illegal U-Turn', 250, 0), + (57, 'Illegally Driving Off-road', 170, 0), + (58, 'Refusing a Lawful Command', 30, 0), + (59, 'Illegally Stopping a Vehicle', 150, 0), + (60, 'Illegal Parking', 70, 0), + (61, 'Failing to Yield to the right', 70, 0), + (62, 'Failure to comply with Vehicle Information', 90, 0), + (63, 'Failing to stop at a Stop Sign ', 105, 0), + (64, 'Failing to stop at a Red Light', 130, 0), + (65, 'Illegal Passing', 100, 0), + (66, 'Driving an illegal Vehicle', 100, 0), + (67, 'Driving without a License', 1500, 0), + (68, 'Hit and Run', 800, 0), + (69, 'Exceeding Speeds Over < 5 mph', 90, 0), + (70, 'Exceeding Speeds Over 5-15 mph', 120, 0), + (71, 'Exceeding Speeds Over 15-30 mph', 180, 0), + (72, 'Exceeding Speeds Over > 30 mph', 300, 0), + (73, 'Impeding traffic flow', 110, 1), + (74, 'Public Intoxication', 90, 1), + (75, 'Disorderly conduct', 90, 1), + (76, 'Obstruction of Justice', 130, 1), + (77, 'Insults towards Civilans', 75, 1), + (78, 'Disrespecting of an LEO', 110, 1), + (79, 'Verbal Threat towards a Civilan', 90, 1), + (80, 'Verbal Threat towards an LEO', 150, 1), + (81, 'Providing False Information', 250, 1), + (82, 'Attempt of Corruption', 1500, 1), + (83, 'Brandishing a weapon in city Limits', 120, 2), + (84, 'Brandishing a Lethal Weapon in city Limits', 300, 2), + (85, 'No Firearms License', 600, 2), + (86, 'Possession of an Illegal Weapon', 700, 2), + (87, 'Possession of Burglary Tools', 300, 2), + (88, 'Grand Theft Auto', 1800, 2), + (89, 'Intent to Sell/Distrube of an illegal Substance', 1500, 2), + (90, 'Frabrication of an Illegal Substance', 1500, 2), + (91, 'Possession of an Illegal Substance ', 650, 2), + (92, 'Kidnapping of a Civilan', 1500, 2), + (93, 'Kidnapping of an LEO', 2000, 2), + (94, 'Robbery', 650, 2), + (95, 'Armed Robbery of a Store', 650, 2), + (96, 'Armed Robbery of a Bank', 1500, 2), + (97, 'Assault on a Civilian', 2000, 3), + (98, 'Assault of an LEO', 2500, 3), + (99, 'Attempt of Murder of a Civilian', 3000, 3), + (100, 'Attempt of Murder of an LEO', 5000, 3), + (101, 'Murder of a Civilian', 10000, 3), + (102, 'Murder of an LEO', 30000, 3), + (103, 'Involuntary manslaughter', 1800, 3), + (104, 'Fraud', 2000, 2); +/*!40000 ALTER TABLE `fine_types` ENABLE KEYS */; + +-- Dumping structure for table es_extended.inventories +CREATE TABLE IF NOT EXISTS `inventories` ( + `name` varchar(255) NOT NULL, + `owner` varchar(64) DEFAULT NULL, + `items` longtext DEFAULT NULL, + PRIMARY KEY (`name`), + KEY `owner` (`owner`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.inventories: ~0 rows (approximately) +/*!40000 ALTER TABLE `inventories` DISABLE KEYS */; +/*!40000 ALTER TABLE `inventories` ENABLE KEYS */; + +-- Dumping structure for table es_extended.items +CREATE TABLE IF NOT EXISTS `items` ( + `name` varchar(64) NOT NULL, + `label` varchar(64) NOT NULL, + `weight` int(11) NOT NULL, + `rare` int(11) NOT NULL, + `can_remove` int(11) NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.items: ~33 rows (approximately) +/*!40000 ALTER TABLE `items` DISABLE KEYS */; +INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES + ('alive_chicken', 'Living chicken', 1, 0, 1), + ('bandage', 'Bandage', 2, 0, 1), + ('beer', 'Beer', 1, 0, 0), + ('blowpipe', 'Blowtorch', 2, 0, 1), + ('bread', 'Bread', 1, 0, 1), + ('cannabis', 'Cannabis', 3, 0, 1), + ('carokit', 'Body Kit', 3, 0, 1), + ('carotool', 'Tools', 2, 0, 1), + ('clothe', 'Cloth', 1, 0, 1), + ('copper', 'Copper', 1, 0, 1), + ('cutted_wood', 'Cut wood', 1, 0, 1), + ('diamond', 'Diamond', 1, 0, 1), + ('essence', 'Gas', 1, 0, 1), + ('fabric', 'Fabric', 1, 0, 1), + ('fish', 'Fish', 1, 0, 1), + ('fixkit', 'Repair Kit', 3, 0, 1), + ('fixtool', 'Repair Tools', 2, 0, 1), + ('gazbottle', 'Gas Bottle', 2, 0, 1), + ('gold', 'Gold', 1, 0, 1), + ('iron', 'Iron', 1, 0, 1), + ('marijuana', 'Marijuana', 2, 0, 1), + ('medikit', 'Medikit', 2, 0, 1), + ('packaged_chicken', 'Chicken fillet', 1, 0, 1), + ('packaged_plank', 'Packaged wood', 1, 0, 1), + ('petrol', 'Oil', 1, 0, 1), + ('petrol_raffin', 'Processed oil', 1, 0, 1), + ('phone', 'Phone', 1, 0, 1), + ('slaughtered_chicken', 'Slaughtered chicken', 1, 0, 1), + ('stone', 'Stone', 1, 0, 1), + ('washed_stone', 'Washed stone', 1, 0, 1), + ('water', 'Water', 1, 0, 1), + ('wood', 'Wood', 1, 0, 1), + ('wool', 'Wool', 1, 0, 1); +/*!40000 ALTER TABLE `items` ENABLE KEYS */; + +-- Dumping structure for table es_extended.jobs +CREATE TABLE IF NOT EXISTS `jobs` ( + `name` varchar(64) NOT NULL, + `label` varchar(64) DEFAULT NULL, + `whitelisted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.jobs: ~15 rows (approximately) +/*!40000 ALTER TABLE `jobs` DISABLE KEYS */; +INSERT INTO `jobs` (`name`, `label`, `whitelisted`) VALUES + ('ambulance', 'EMS', 0), + ('banker', 'Banker', 0), + ('cardealer', 'Cardealer', 0), + ('fisherman', 'Fisherman', 0), + ('fueler', 'Fueler', 0), + ('lumberjack', 'Lumberjack', 0), + ('mechanic', 'Mechanic', 0), + ('miner', 'Miner', 0), + ('police', 'LSPD', 0), + ('realestateagent', 'Real Estate Agent', 0), + ('reporter', 'Reporter', 0), + ('slaughterer', 'Butcher', 0), + ('tailor', 'Tailor', 0), + ('taxi', 'Taxi', 0), + ('unemployed', 'Unemployed', 0); +/*!40000 ALTER TABLE `jobs` ENABLE KEYS */; + +-- Dumping structure for table es_extended.job_grades +CREATE TABLE IF NOT EXISTS `job_grades` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(32) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(64) NOT NULL, + `label` varchar(64) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, + PRIMARY KEY (`id`), + KEY `job_name` (`job_name`), + KEY `grade` (`grade`) +) ENGINE=InnoDB AUTO_INCREMENT=41; + +-- Dumping data for table es_extended.job_grades: ~40 rows (approximately) +/*!40000 ALTER TABLE `job_grades` DISABLE KEYS */; +INSERT INTO `job_grades` (`id`, `job_name`, `grade`, `name`, `label`, `salary`, `skin_male`, `skin_female`) VALUES + (1, 'unemployed', 0, 'unemployed', 'Unemployed', 200, '{}', '{}'), + (2, 'ambulance', 0, 'ambulance', 'Paramedic', 20, '{"tshirt_2":0,"hair_color_1":5,"glasses_2":3,"shoes":9,"torso_2":3,"hair_color_2":0,"pants_1":24,"glasses_1":4,"hair_1":2,"sex":0,"decals_2":0,"tshirt_1":15,"helmet_1":8,"helmet_2":0,"arms":92,"face":19,"decals_1":60,"torso_1":13,"hair_2":0,"skin":34,"pants_2":5}', '{"tshirt_2":3,"decals_2":0,"glasses":0,"hair_1":2,"torso_1":73,"shoes":1,"hair_color_2":0,"glasses_1":19,"skin":13,"face":6,"pants_2":5,"tshirt_1":75,"pants_1":37,"helmet_1":57,"torso_2":0,"arms":14,"sex":1,"glasses_2":0,"decals_1":0,"hair_2":0,"helmet_2":0,"hair_color_1":0}'), + (3, 'ambulance', 1, 'doctor', 'Doctor', 40, '{"tshirt_2":0,"hair_color_1":5,"glasses_2":3,"shoes":9,"torso_2":3,"hair_color_2":0,"pants_1":24,"glasses_1":4,"hair_1":2,"sex":0,"decals_2":0,"tshirt_1":15,"helmet_1":8,"helmet_2":0,"arms":92,"face":19,"decals_1":60,"torso_1":13,"hair_2":0,"skin":34,"pants_2":5}', '{"tshirt_2":3,"decals_2":0,"glasses":0,"hair_1":2,"torso_1":73,"shoes":1,"hair_color_2":0,"glasses_1":19,"skin":13,"face":6,"pants_2":5,"tshirt_1":75,"pants_1":37,"helmet_1":57,"torso_2":0,"arms":14,"sex":1,"glasses_2":0,"decals_1":0,"hair_2":0,"helmet_2":0,"hair_color_1":0}'), + (4, 'ambulance', 2, 'chief_doctor', 'Chief doctor', 60, '{"tshirt_2":0,"hair_color_1":5,"glasses_2":3,"shoes":9,"torso_2":3,"hair_color_2":0,"pants_1":24,"glasses_1":4,"hair_1":2,"sex":0,"decals_2":0,"tshirt_1":15,"helmet_1":8,"helmet_2":0,"arms":92,"face":19,"decals_1":60,"torso_1":13,"hair_2":0,"skin":34,"pants_2":5}', '{"tshirt_2":3,"decals_2":0,"glasses":0,"hair_1":2,"torso_1":73,"shoes":1,"hair_color_2":0,"glasses_1":19,"skin":13,"face":6,"pants_2":5,"tshirt_1":75,"pants_1":37,"helmet_1":57,"torso_2":0,"arms":14,"sex":1,"glasses_2":0,"decals_1":0,"hair_2":0,"helmet_2":0,"hair_color_1":0}'), + (5, 'ambulance', 3, 'boss', 'Surgeon', 80, '{"tshirt_2":0,"hair_color_1":5,"glasses_2":3,"shoes":9,"torso_2":3,"hair_color_2":0,"pants_1":24,"glasses_1":4,"hair_1":2,"sex":0,"decals_2":0,"tshirt_1":15,"helmet_1":8,"helmet_2":0,"arms":92,"face":19,"decals_1":60,"torso_1":13,"hair_2":0,"skin":34,"pants_2":5}', '{"tshirt_2":3,"decals_2":0,"glasses":0,"hair_1":2,"torso_1":73,"shoes":1,"hair_color_2":0,"glasses_1":19,"skin":13,"face":6,"pants_2":5,"tshirt_1":75,"pants_1":37,"helmet_1":57,"torso_2":0,"arms":14,"sex":1,"glasses_2":0,"decals_1":0,"hair_2":0,"helmet_2":0,"hair_color_1":0}'), + (6, 'banker', 0, 'advisor', 'Advisor', 10, '{}', '{}'), + (7, 'banker', 1, 'banker', 'Banker', 20, '{}', '{}'), + (8, 'banker', 2, 'business_banker', 'Investment banker', 30, '{}', '{}'), + (9, 'banker', 3, 'trader', 'Trader', 40, '{}', '{}'), + (10, 'banker', 4, 'boss', 'Boss', 0, '{}', '{}'), + (11, 'lumberjack', 0, 'employee', 'Employee', 0, '{}', '{}'), + (12, 'fisherman', 0, 'employee', 'Employee', 0, '{}', '{}'), + (13, 'fueler', 0, 'employee', 'Employee', 0, '{}', '{}'), + (14, 'reporter', 0, 'employee', 'Employee', 0, '{}', '{}'), + (15, 'tailor', 0, 'employee', 'Employee', 0, '{"mask_1":0,"arms":1,"glasses_1":0,"hair_color_2":4,"makeup_1":0,"face":19,"glasses":0,"mask_2":0,"makeup_3":0,"skin":29,"helmet_2":0,"lipstick_4":0,"sex":0,"torso_1":24,"makeup_2":0,"bags_2":0,"chain_2":0,"ears_1":-1,"bags_1":0,"bproof_1":0,"shoes_2":0,"lipstick_2":0,"chain_1":0,"tshirt_1":0,"eyebrows_3":0,"pants_2":0,"beard_4":0,"torso_2":0,"beard_2":6,"ears_2":0,"hair_2":0,"shoes_1":36,"tshirt_2":0,"beard_3":0,"hair_1":2,"hair_color_1":0,"pants_1":48,"helmet_1":-1,"bproof_2":0,"eyebrows_4":0,"eyebrows_2":0,"decals_1":0,"age_2":0,"beard_1":5,"shoes":10,"lipstick_1":0,"eyebrows_1":0,"glasses_2":0,"makeup_4":0,"decals_2":0,"lipstick_3":0,"age_1":0}', '{"mask_1":0,"arms":5,"glasses_1":5,"hair_color_2":4,"makeup_1":0,"face":19,"glasses":0,"mask_2":0,"makeup_3":0,"skin":29,"helmet_2":0,"lipstick_4":0,"sex":1,"torso_1":52,"makeup_2":0,"bags_2":0,"chain_2":0,"ears_1":-1,"bags_1":0,"bproof_1":0,"shoes_2":1,"lipstick_2":0,"chain_1":0,"tshirt_1":23,"eyebrows_3":0,"pants_2":0,"beard_4":0,"torso_2":0,"beard_2":6,"ears_2":0,"hair_2":0,"shoes_1":42,"tshirt_2":4,"beard_3":0,"hair_1":2,"hair_color_1":0,"pants_1":36,"helmet_1":-1,"bproof_2":0,"eyebrows_4":0,"eyebrows_2":0,"decals_1":0,"age_2":0,"beard_1":5,"shoes":10,"lipstick_1":0,"eyebrows_1":0,"glasses_2":0,"makeup_4":0,"decals_2":0,"lipstick_3":0,"age_1":0}'), + (16, 'miner', 0, 'employee', 'Employee', 0, '{"tshirt_2":1,"ears_1":8,"glasses_1":15,"torso_2":0,"ears_2":2,"glasses_2":3,"shoes_2":1,"pants_1":75,"shoes_1":51,"bags_1":0,"helmet_2":0,"pants_2":7,"torso_1":71,"tshirt_1":59,"arms":2,"bags_2":0,"helmet_1":0}', '{}'), + (17, 'slaughterer', 0, 'employee', 'Employee', 0, '{"age_1":0,"glasses_2":0,"beard_1":5,"decals_2":0,"beard_4":0,"shoes_2":0,"tshirt_2":0,"lipstick_2":0,"hair_2":0,"arms":67,"pants_1":36,"skin":29,"eyebrows_2":0,"shoes":10,"helmet_1":-1,"lipstick_1":0,"helmet_2":0,"hair_color_1":0,"glasses":0,"makeup_4":0,"makeup_1":0,"hair_1":2,"bproof_1":0,"bags_1":0,"mask_1":0,"lipstick_3":0,"chain_1":0,"eyebrows_4":0,"sex":0,"torso_1":56,"beard_2":6,"shoes_1":12,"decals_1":0,"face":19,"lipstick_4":0,"tshirt_1":15,"mask_2":0,"age_2":0,"eyebrows_3":0,"chain_2":0,"glasses_1":0,"ears_1":-1,"bags_2":0,"ears_2":0,"torso_2":0,"bproof_2":0,"makeup_2":0,"eyebrows_1":0,"makeup_3":0,"pants_2":0,"beard_3":0,"hair_color_2":4}', '{"age_1":0,"glasses_2":0,"beard_1":5,"decals_2":0,"beard_4":0,"shoes_2":0,"tshirt_2":0,"lipstick_2":0,"hair_2":0,"arms":72,"pants_1":45,"skin":29,"eyebrows_2":0,"shoes":10,"helmet_1":-1,"lipstick_1":0,"helmet_2":0,"hair_color_1":0,"glasses":0,"makeup_4":0,"makeup_1":0,"hair_1":2,"bproof_1":0,"bags_1":0,"mask_1":0,"lipstick_3":0,"chain_1":0,"eyebrows_4":0,"sex":1,"torso_1":49,"beard_2":6,"shoes_1":24,"decals_1":0,"face":19,"lipstick_4":0,"tshirt_1":9,"mask_2":0,"age_2":0,"eyebrows_3":0,"chain_2":0,"glasses_1":5,"ears_1":-1,"bags_2":0,"ears_2":0,"torso_2":0,"bproof_2":0,"makeup_2":0,"eyebrows_1":0,"makeup_3":0,"pants_2":0,"beard_3":0,"hair_color_2":4}'), + (18, 'mechanic', 0, 'recrue', 'Recruit', 12, '{}', '{}'), + (19, 'mechanic', 1, 'novice', 'beginner', 24, '{}', '{}'), + (20, 'mechanic', 2, 'experimente', 'experienced', 36, '{}', '{}'), + (21, 'mechanic', 3, 'chief', 'Leader', 48, '{}', '{}'), + (22, 'mechanic', 4, 'boss', 'Boss', 0, '{}', '{}'), + (23, 'police', 0, 'recruit', 'Recruit', 20, '{}', '{}'), + (24, 'police', 1, 'officer', 'Officier', 40, '{}', '{}'), + (25, 'police', 2, 'sergeant', 'Sergent', 60, '{}', '{}'), + (26, 'police', 3, 'lieutenant', 'Lieutenant', 85, '{}', '{}'), + (27, 'police', 4, 'boss', 'Commandant', 100, '{}', '{}'), + (28, 'realestateagent', 0, 'location', 'Renting Agent', 10, '{}', '{}'), + (29, 'realestateagent', 1, 'vendeur', 'Agent', 25, '{}', '{}'), + (30, 'realestateagent', 2, 'gestion', 'Management', 40, '{}', '{}'), + (31, 'realestateagent', 3, 'boss', 'Broker', 0, '{}', '{}'), + (32, 'taxi', 0, 'recrue', 'Recruit', 12, '{"hair_2":0,"hair_color_2":0,"torso_1":32,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":31,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":0,"age_2":0,"glasses_2":0,"ears_2":0,"arms":27,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":0,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":0,"bproof_1":0,"mask_1":0,"decals_1":1,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":10,"pants_1":24}', '{"hair_2":0,"hair_color_2":0,"torso_1":57,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":38,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":1,"age_2":0,"glasses_2":0,"ears_2":0,"arms":21,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":1,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":5,"bproof_1":0,"mask_1":0,"decals_1":1,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":49,"pants_1":11}'), + (33, 'taxi', 1, 'novice', 'Novice', 24, '{"hair_2":0,"hair_color_2":0,"torso_1":32,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":31,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":0,"age_2":0,"glasses_2":0,"ears_2":0,"arms":27,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":0,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":0,"bproof_1":0,"mask_1":0,"decals_1":1,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":10,"pants_1":24}', '{"hair_2":0,"hair_color_2":0,"torso_1":57,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":38,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":1,"age_2":0,"glasses_2":0,"ears_2":0,"arms":21,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":1,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":5,"bproof_1":0,"mask_1":0,"decals_1":1,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":49,"pants_1":11}'), + (34, 'taxi', 2, 'experimente', 'Experienced', 36, '{"hair_2":0,"hair_color_2":0,"torso_1":26,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":57,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":4,"age_2":0,"glasses_2":0,"ears_2":0,"arms":11,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":0,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":0,"bproof_1":0,"mask_1":0,"decals_1":0,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":10,"pants_1":24}', '{"hair_2":0,"hair_color_2":0,"torso_1":57,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":38,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":1,"age_2":0,"glasses_2":0,"ears_2":0,"arms":21,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":1,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":5,"bproof_1":0,"mask_1":0,"decals_1":1,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":49,"pants_1":11}'), + (35, 'taxi', 3, 'uber', 'Uber', 48, '{"hair_2":0,"hair_color_2":0,"torso_1":26,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":57,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":4,"age_2":0,"glasses_2":0,"ears_2":0,"arms":11,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":0,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":0,"bproof_1":0,"mask_1":0,"decals_1":0,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":10,"pants_1":24}', '{"hair_2":0,"hair_color_2":0,"torso_1":57,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":38,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":1,"age_2":0,"glasses_2":0,"ears_2":0,"arms":21,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":1,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":5,"bproof_1":0,"mask_1":0,"decals_1":1,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":49,"pants_1":11}'), + (36, 'taxi', 4, 'boss', 'Boss', 0, '{"hair_2":0,"hair_color_2":0,"torso_1":29,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":31,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":4,"age_2":0,"glasses_2":0,"ears_2":0,"arms":1,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":0,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":0,"bproof_1":0,"mask_1":0,"decals_1":0,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":4,"eyebrows_1":0,"face":0,"shoes_1":10,"pants_1":24}', '{"hair_2":0,"hair_color_2":0,"torso_1":57,"bags_1":0,"helmet_2":0,"chain_2":0,"eyebrows_3":0,"makeup_3":0,"makeup_2":0,"tshirt_1":38,"makeup_1":0,"bags_2":0,"makeup_4":0,"eyebrows_4":0,"chain_1":0,"lipstick_4":0,"bproof_2":0,"hair_color_1":0,"decals_2":0,"pants_2":1,"age_2":0,"glasses_2":0,"ears_2":0,"arms":21,"lipstick_1":0,"ears_1":-1,"mask_2":0,"sex":1,"lipstick_3":0,"helmet_1":-1,"shoes_2":0,"beard_2":0,"beard_1":0,"lipstick_2":0,"beard_4":0,"glasses_1":5,"bproof_1":0,"mask_1":0,"decals_1":1,"hair_1":0,"eyebrows_2":0,"beard_3":0,"age_1":0,"tshirt_2":0,"skin":0,"torso_2":0,"eyebrows_1":0,"face":0,"shoes_1":49,"pants_1":11}'), + (37, 'cardealer', 0, 'recruit', 'Recruit', 10, '{}', '{}'), + (38, 'cardealer', 1, 'novice', 'Novice', 25, '{}', '{}'), + (39, 'cardealer', 2, 'experienced', 'Experienced', 40, '{}', '{}'), + (40, 'cardealer', 3, 'boss', 'Boss', 0, '{}', '{}'); +/*!40000 ALTER TABLE `job_grades` ENABLE KEYS */; + +-- Dumping structure for table es_extended.licenses +CREATE TABLE IF NOT EXISTS `licenses` ( + `type` varchar(60) NOT NULL, + `label` varchar(60) NOT NULL, + PRIMARY KEY (`type`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.licenses: ~7 rows (approximately) +/*!40000 ALTER TABLE `licenses` DISABLE KEYS */; +INSERT INTO `licenses` (`type`, `label`) VALUES + ('boat', 'Boat License'), + ('dmv', 'Traffic Laws'), + ('drive', 'Drivers license'), + ('drive_bike', 'Motorcycle licence'), + ('drive_truck', 'Truck license'), + ('weapon', 'Weapon License'), + ('weed_processing', 'Weed Processing License'); +/*!40000 ALTER TABLE `licenses` ENABLE KEYS */; + +-- Dumping structure for table es_extended.migrations +CREATE TABLE IF NOT EXISTS `migrations` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `module` varchar(64) DEFAULT NULL, + `last` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3; + +-- Dumping data for table es_extended.migrations: ~2 rows (approximately) +/*!40000 ALTER TABLE `migrations` DISABLE KEYS */; +INSERT INTO `migrations` (`id`, `module`, `last`) VALUES + (1, 'skin', 0), + (2, 'society', 0); +/*!40000 ALTER TABLE `migrations` ENABLE KEYS */; + +-- Dumping structure for table es_extended.owned_properties +CREATE TABLE IF NOT EXISTS `owned_properties` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `price` double NOT NULL, + `rented` int(11) NOT NULL, + `owner` varchar(60) NOT NULL, + PRIMARY KEY (`id`), + KEY `name` (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.owned_properties: ~0 rows (approximately) +/*!40000 ALTER TABLE `owned_properties` DISABLE KEYS */; +/*!40000 ALTER TABLE `owned_properties` ENABLE KEYS */; + +-- Dumping structure for table es_extended.owned_vehicles +CREATE TABLE IF NOT EXISTS `owned_vehicles` ( + `owner` varchar(60) NOT NULL, + `plate` varchar(12) NOT NULL, + `vehicle` longtext DEFAULT NULL, + `type` varchar(20) NOT NULL DEFAULT 'car', + `job` varchar(20) DEFAULT NULL, + `stored` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`plate`), + KEY `owner` (`owner`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.owned_vehicles: ~0 rows (approximately) +/*!40000 ALTER TABLE `owned_vehicles` DISABLE KEYS */; +/*!40000 ALTER TABLE `owned_vehicles` ENABLE KEYS */; + +-- Dumping structure for table es_extended.properties +CREATE TABLE IF NOT EXISTS `properties` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `label` varchar(255) DEFAULT NULL, + `entering` varchar(255) DEFAULT NULL, + `exit` varchar(255) DEFAULT NULL, + `inside` varchar(255) DEFAULT NULL, + `outside` varchar(255) DEFAULT NULL, + `ipls` varchar(255) DEFAULT '[]', + `gateway` varchar(255) DEFAULT NULL, + `is_single` int(11) DEFAULT NULL, + `is_room` int(11) DEFAULT NULL, + `is_gateway` int(11) DEFAULT NULL, + `room_menu` varchar(255) DEFAULT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=73; + +-- Dumping data for table es_extended.properties: ~72 rows (approximately) +/*!40000 ALTER TABLE `properties` DISABLE KEYS */; +INSERT INTO `properties` (`id`, `name`, `label`, `entering`, `exit`, `inside`, `outside`, `ipls`, `gateway`, `is_single`, `is_room`, `is_gateway`, `room_menu`, `price`) VALUES + (1, 'WhispymoundDrive', '2677 Whispymound Drive', '{"y":564.89,"z":182.959,"x":119.384}', '{"x":117.347,"y":559.506,"z":183.304}', '{"y":557.032,"z":183.301,"x":118.037}', '{"y":567.798,"z":182.131,"x":119.249}', '[]', NULL, 1, 1, 0, '{"x":118.748,"y":566.573,"z":175.697}', 1500000), + (2, 'NorthConkerAvenue2045', '2045 North Conker Avenue', '{"x":372.796,"y":428.327,"z":144.685}', '{"x":373.548,"y":422.982,"z":144.907}', '{"y":420.075,"z":145.904,"x":372.161}', '{"x":372.454,"y":432.886,"z":143.443}', '[]', NULL, 1, 1, 0, '{"x":377.349,"y":429.422,"z":137.3}', 1500000), + (3, 'RichardMajesticApt2', 'Richard Majestic, Apt 2', '{"y":-379.165,"z":37.961,"x":-936.363}', '{"y":-365.476,"z":113.274,"x":-913.097}', '{"y":-367.637,"z":113.274,"x":-918.022}', '{"y":-382.023,"z":37.961,"x":-943.626}', '[]', NULL, 1, 1, 0, '{"x":-927.554,"y":-377.744,"z":112.674}', 1700000), + (4, 'NorthConkerAvenue2044', '2044 North Conker Avenue', '{"y":440.8,"z":146.702,"x":346.964}', '{"y":437.456,"z":148.394,"x":341.683}', '{"y":435.626,"z":148.394,"x":339.595}', '{"x":350.535,"y":443.329,"z":145.764}', '[]', NULL, 1, 1, 0, '{"x":337.726,"y":436.985,"z":140.77}', 1500000), + (5, 'WildOatsDrive', '3655 Wild Oats Drive', '{"y":502.696,"z":136.421,"x":-176.003}', '{"y":497.817,"z":136.653,"x":-174.349}', '{"y":495.069,"z":136.666,"x":-173.331}', '{"y":506.412,"z":135.0664,"x":-177.927}', '[]', NULL, 1, 1, 0, '{"x":-174.725,"y":493.095,"z":129.043}', 1500000), + (6, 'HillcrestAvenue2862', '2862 Hillcrest Avenue', '{"y":596.58,"z":142.641,"x":-686.554}', '{"y":591.988,"z":144.392,"x":-681.728}', '{"y":590.608,"z":144.392,"x":-680.124}', '{"y":599.019,"z":142.059,"x":-689.492}', '[]', NULL, 1, 1, 0, '{"x":-680.46,"y":588.6,"z":136.769}', 1500000), + (7, 'LowEndApartment', 'Appartement de base', '{"y":-1078.735,"z":28.4031,"x":292.528}', '{"y":-1007.152,"z":-102.002,"x":265.845}', '{"y":-1002.802,"z":-100.008,"x":265.307}', '{"y":-1078.669,"z":28.401,"x":296.738}', '[]', NULL, 1, 1, 0, '{"x":265.916,"y":-999.38,"z":-100.008}', 562500), + (8, 'MadWayneThunder', '2113 Mad Wayne Thunder', '{"y":454.955,"z":96.462,"x":-1294.433}', '{"x":-1289.917,"y":449.541,"z":96.902}', '{"y":446.322,"z":96.899,"x":-1289.642}', '{"y":455.453,"z":96.517,"x":-1298.851}', '[]', NULL, 1, 1, 0, '{"x":-1287.306,"y":455.901,"z":89.294}', 1500000), + (9, 'HillcrestAvenue2874', '2874 Hillcrest Avenue', '{"x":-853.346,"y":696.678,"z":147.782}', '{"y":690.875,"z":151.86,"x":-859.961}', '{"y":688.361,"z":151.857,"x":-859.395}', '{"y":701.628,"z":147.773,"x":-855.007}', '[]', NULL, 1, 1, 0, '{"x":-858.543,"y":697.514,"z":144.253}', 1500000), + (10, 'HillcrestAvenue2868', '2868 Hillcrest Avenue', '{"y":620.494,"z":141.588,"x":-752.82}', '{"y":618.62,"z":143.153,"x":-759.317}', '{"y":617.629,"z":143.153,"x":-760.789}', '{"y":621.281,"z":141.254,"x":-750.919}', '[]', NULL, 1, 1, 0, '{"x":-762.504,"y":618.992,"z":135.53}', 1500000), + (11, 'TinselTowersApt12', 'Tinsel Towers, Apt 42', '{"y":37.025,"z":42.58,"x":-618.299}', '{"y":58.898,"z":97.2,"x":-603.301}', '{"y":58.941,"z":97.2,"x":-608.741}', '{"y":30.603,"z":42.524,"x":-620.017}', '[]', NULL, 1, 1, 0, '{"x":-622.173,"y":54.585,"z":96.599}', 1700000), + (12, 'MiltonDrive', 'Milton Drive', '{"x":-775.17,"y":312.01,"z":84.658}', NULL, NULL, '{"x":-775.346,"y":306.776,"z":84.7}', '[]', NULL, 0, 0, 1, NULL, 0), + (13, 'Modern1Apartment', 'Appartement Moderne 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_01_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-766.661,"y":327.672,"z":210.396}', 1300000), + (14, 'Modern2Apartment', 'Appartement Moderne 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_01_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.735,"y":326.757,"z":186.313}', 1300000), + (15, 'Modern3Apartment', 'Appartement Moderne 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_01_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.386,"y":330.782,"z":195.08}', 1300000), + (16, 'Mody1Apartment', 'Appartement Mode 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_02_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-766.615,"y":327.878,"z":210.396}', 1300000), + (17, 'Mody2Apartment', 'Appartement Mode 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_02_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.297,"y":327.092,"z":186.313}', 1300000), + (18, 'Mody3Apartment', 'Appartement Mode 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_02_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.303,"y":330.932,"z":195.085}', 1300000), + (19, 'Vibrant1Apartment', 'Appartement Vibrant 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_03_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.885,"y":327.641,"z":210.396}', 1300000), + (20, 'Vibrant2Apartment', 'Appartement Vibrant 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_03_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.607,"y":327.344,"z":186.313}', 1300000), + (21, 'Vibrant3Apartment', 'Appartement Vibrant 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_03_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.525,"y":330.851,"z":195.085}', 1300000), + (22, 'Sharp1Apartment', 'Appartement Persan 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_04_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-766.527,"y":327.89,"z":210.396}', 1300000), + (23, 'Sharp2Apartment', 'Appartement Persan 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_04_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.642,"y":326.497,"z":186.313}', 1300000), + (24, 'Sharp3Apartment', 'Appartement Persan 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_04_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.503,"y":331.318,"z":195.085}', 1300000), + (25, 'Monochrome1Apartment', 'Appartement Monochrome 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_05_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-766.289,"y":328.086,"z":210.396}', 1300000), + (26, 'Monochrome2Apartment', 'Appartement Monochrome 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_05_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.692,"y":326.762,"z":186.313}', 1300000), + (27, 'Monochrome3Apartment', 'Appartement Monochrome 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_05_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.094,"y":330.976,"z":195.085}', 1300000), + (28, 'Seductive1Apartment', 'Appartement Séduisant 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_06_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-766.263,"y":328.104,"z":210.396}', 1300000), + (29, 'Seductive2Apartment', 'Appartement Séduisant 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_06_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.655,"y":326.611,"z":186.313}', 1300000), + (30, 'Seductive3Apartment', 'Appartement Séduisant 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_06_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.3,"y":331.414,"z":195.085}', 1300000), + (31, 'Regal1Apartment', 'Appartement Régal 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_07_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.956,"y":328.257,"z":210.396}', 1300000), + (32, 'Regal2Apartment', 'Appartement Régal 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_07_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.545,"y":326.659,"z":186.313}', 1300000), + (33, 'Regal3Apartment', 'Appartement Régal 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_07_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.087,"y":331.429,"z":195.123}', 1300000), + (34, 'Aqua1Apartment', 'Appartement Aqua 1', NULL, '{"x":-784.194,"y":323.636,"z":210.997}', '{"x":-779.751,"y":323.385,"z":210.997}', NULL, '["apa_v_mp_h_08_a"]', 'MiltonDrive', 0, 1, 0, '{"x":-766.187,"y":328.47,"z":210.396}', 1300000), + (35, 'Aqua2Apartment', 'Appartement Aqua 2', NULL, '{"x":-786.8663,"y":315.764,"z":186.913}', '{"x":-781.808,"y":315.866,"z":186.913}', NULL, '["apa_v_mp_h_08_c"]', 'MiltonDrive', 0, 1, 0, '{"x":-795.658,"y":326.563,"z":186.313}', 1300000), + (36, 'Aqua3Apartment', 'Appartement Aqua 3', NULL, '{"x":-774.012,"y":342.042,"z":195.686}', '{"x":-779.057,"y":342.063,"z":195.686}', NULL, '["apa_v_mp_h_08_b"]', 'MiltonDrive', 0, 1, 0, '{"x":-765.287,"y":331.084,"z":195.086}', 1300000), + (37, 'IntegrityWay', '4 Integrity Way', '{"x":-47.804,"y":-585.867,"z":36.956}', NULL, NULL, '{"x":-54.178,"y":-583.762,"z":35.798}', '[]', NULL, 0, 0, 1, NULL, 0), + (38, 'IntegrityWay28', '4 Integrity Way - Apt 28', NULL, '{"x":-31.409,"y":-594.927,"z":79.03}', '{"x":-26.098,"y":-596.909,"z":79.03}', NULL, '[]', 'IntegrityWay', 0, 1, 0, '{"x":-11.923,"y":-597.083,"z":78.43}', 1700000), + (39, 'IntegrityWay30', '4 Integrity Way - Apt 30', NULL, '{"x":-17.702,"y":-588.524,"z":89.114}', '{"x":-16.21,"y":-582.569,"z":89.114}', NULL, '[]', 'IntegrityWay', 0, 1, 0, '{"x":-26.327,"y":-588.384,"z":89.123}', 1700000), + (40, 'DellPerroHeights', 'Dell Perro Heights', '{"x":-1447.06,"y":-538.28,"z":33.74}', NULL, NULL, '{"x":-1440.022,"y":-548.696,"z":33.74}', '[]', NULL, 0, 0, 1, NULL, 0), + (41, 'DellPerroHeightst4', 'Dell Perro Heights - Apt 28', NULL, '{"x":-1452.125,"y":-540.591,"z":73.044}', '{"x":-1455.435,"y":-535.79,"z":73.044}', NULL, '[]', 'DellPerroHeights', 0, 1, 0, '{"x":-1467.058,"y":-527.571,"z":72.443}', 1700000), + (42, 'DellPerroHeightst7', 'Dell Perro Heights - Apt 30', NULL, '{"x":-1451.562,"y":-523.535,"z":55.928}', '{"x":-1456.02,"y":-519.209,"z":55.929}', NULL, '[]', 'DellPerroHeights', 0, 1, 0, '{"x":-1457.026,"y":-530.219,"z":55.937}', 1700000), + (43, 'MazeBankBuilding', 'Maze Bank Building', '{"x":-79.18,"y":-795.92,"z":43.35}', NULL, NULL, '{"x":-72.50,"y":-786.92,"z":43.40}', '[]', NULL, 0, 0, 1, NULL, 0), + (44, 'OldSpiceWarm', 'Old Spice Warm', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_01a"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (45, 'OldSpiceClassical', 'Old Spice Classical', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_01b"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (46, 'OldSpiceVintage', 'Old Spice Vintage', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_01c"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (47, 'ExecutiveRich', 'Executive Rich', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_02b"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (48, 'ExecutiveCool', 'Executive Cool', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_02c"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (49, 'ExecutiveContrast', 'Executive Contrast', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_02a"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (50, 'PowerBrokerIce', 'Power Broker Ice', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_03a"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (51, 'PowerBrokerConservative', 'Power Broker Conservative', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_03b"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (52, 'PowerBrokerPolished', 'Power Broker Polished', NULL, '{"x":-75.69,"y":-827.08,"z":242.43}', '{"x":-75.51,"y":-823.90,"z":242.43}', NULL, '["ex_dt1_11_office_03c"]', 'MazeBankBuilding', 0, 1, 0, '{"x":-71.81,"y":-814.34,"z":242.39}', 5000000), + (53, 'LomBank', 'Lom Bank', '{"x":-1581.36,"y":-558.23,"z":34.07}', NULL, NULL, '{"x":-1583.60,"y":-555.12,"z":34.07}', '[]', NULL, 0, 0, 1, NULL, 0), + (54, 'LBOldSpiceWarm', 'LB Old Spice Warm', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_01a"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (55, 'LBOldSpiceClassical', 'LB Old Spice Classical', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_01b"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (56, 'LBOldSpiceVintage', 'LB Old Spice Vintage', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_01c"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (57, 'LBExecutiveRich', 'LB Executive Rich', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_02b"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (58, 'LBExecutiveCool', 'LB Executive Cool', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_02c"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (59, 'LBExecutiveContrast', 'LB Executive Contrast', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_02a"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (60, 'LBPowerBrokerIce', 'LB Power Broker Ice', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_03a"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (61, 'LBPowerBrokerConservative', 'LB Power Broker Conservative', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_03b"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (62, 'LBPowerBrokerPolished', 'LB Power Broker Polished', NULL, '{"x":-1579.53,"y":-564.89,"z":107.62}', '{"x":-1576.42,"y":-567.57,"z":107.62}', NULL, '["ex_sm_13_office_03c"]', 'LomBank', 0, 1, 0, '{"x":-1571.26,"y":-575.76,"z":107.52}', 3500000), + (63, 'MazeBankWest', 'Maze Bank West', '{"x":-1379.58,"y":-499.63,"z":32.22}', NULL, NULL, '{"x":-1378.95,"y":-502.82,"z":32.22}', '[]', NULL, 0, 0, 1, NULL, 0), + (64, 'MBWOldSpiceWarm', 'MBW Old Spice Warm', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_01a"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (65, 'MBWOldSpiceClassical', 'MBW Old Spice Classical', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_01b"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (66, 'MBWOldSpiceVintage', 'MBW Old Spice Vintage', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_01c"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (67, 'MBWExecutiveRich', 'MBW Executive Rich', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_02b"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (68, 'MBWExecutiveCool', 'MBW Executive Cool', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_02c"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (69, 'MBWExecutive Contrast', 'MBW Executive Contrast', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_02a"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (70, 'MBWPowerBrokerIce', 'MBW Power Broker Ice', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_03a"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (71, 'MBWPowerBrokerConvservative', 'MBW Power Broker Convservative', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_03b"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000), + (72, 'MBWPowerBrokerPolished', 'MBW Power Broker Polished', NULL, '{"x":-1392.74,"y":-480.18,"z":71.14}', '{"x":-1389.43,"y":-479.01,"z":71.14}', NULL, '["ex_sm_15_office_03c"]', 'MazeBankWest', 0, 1, 0, '{"x":-1390.76,"y":-479.22,"z":72.04}', 2700000); +/*!40000 ALTER TABLE `properties` ENABLE KEYS */; + +-- Dumping structure for table es_extended.rented_vehicles +CREATE TABLE IF NOT EXISTS `rented_vehicles` ( + `vehicle` varchar(60) NOT NULL, + `plate` varchar(12) NOT NULL, + `player_name` varchar(255) NOT NULL, + `base_price` int(11) NOT NULL, + `rent_price` int(11) NOT NULL, + `owner` varchar(60) NOT NULL, + PRIMARY KEY (`plate`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.rented_vehicles: ~0 rows (approximately) +/*!40000 ALTER TABLE `rented_vehicles` DISABLE KEYS */; +/*!40000 ALTER TABLE `rented_vehicles` ENABLE KEYS */; + +-- Dumping structure for table es_extended.shops +CREATE TABLE IF NOT EXISTS `shops` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `store` varchar(100) NOT NULL, + `item` varchar(100) NOT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `store` (`store`) +) ENGINE=InnoDB AUTO_INCREMENT=10; + +-- Dumping data for table es_extended.shops: ~9 rows (approximately) +/*!40000 ALTER TABLE `shops` DISABLE KEYS */; +INSERT INTO `shops` (`id`, `store`, `item`, `price`) VALUES + (1, 'TwentyFourSeven', 'bread', 30), + (2, 'TwentyFourSeven', 'water', 15), + (3, 'RobsLiquor', 'bread', 30), + (4, 'RobsLiquor', 'water', 15), + (5, 'LTDgasoline', 'bread', 30), + (6, 'LTDgasoline', 'water', 15), + (7, 'TwentyFourSeven', 'beer', 45), + (8, 'RobsLiquor', 'beer', 45), + (9, 'LTDgasoline', 'beer', 45); +/*!40000 ALTER TABLE `shops` ENABLE KEYS */; + +-- Dumping structure for table es_extended.society_moneywash +CREATE TABLE IF NOT EXISTS `society_moneywash` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(60) NOT NULL, + `society` varchar(60) NOT NULL, + `amount` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.society_moneywash: ~0 rows (approximately) +/*!40000 ALTER TABLE `society_moneywash` DISABLE KEYS */; +/*!40000 ALTER TABLE `society_moneywash` ENABLE KEYS */; + +-- Dumping structure for table es_extended.users +CREATE TABLE IF NOT EXISTS `users` ( + `identifier` varchar(40) NOT NULL, + `name` longtext DEFAULT NULL, + `accounts` longtext DEFAULT NULL, + `group` varchar(64) DEFAULT 'user', + `inventory` longtext DEFAULT NULL, + `job` varchar(32) DEFAULT 'unemployed', + `job_grade` int(11) DEFAULT 0, + `loadout` longtext DEFAULT NULL, + `position` varchar(255) DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}', + `is_dead` int(11) DEFAULT 0, + `dob` varchar(10) DEFAULT NULL, + `is_male` int(11) DEFAULT 1, + `accessories` longtext DEFAULT NULL, + `firstname` varchar(16) DEFAULT NULL, + `lastname` varchar(16) DEFAULT NULL, + `dateofbirth` varchar(10) DEFAULT NULL, + `sex` varchar(1) DEFAULT NULL, + `height` int(11) DEFAULT NULL, + `phone_number` varchar(20) DEFAULT NULL, + `last_property` varchar(255) DEFAULT NULL, + `skin` longtext DEFAULT NULL, + `status` longtext DEFAULT NULL, + PRIMARY KEY (`identifier`), + UNIQUE KEY `index_users_phone_number` (`phone_number`) +) ENGINE=InnoDB; + +-- Dumping structure for table es_extended.user_contacts +CREATE TABLE IF NOT EXISTS `user_contacts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(60) NOT NULL, + `name` varchar(100) NOT NULL, + `number` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `index_user_contacts_identifier_name_number` (`identifier`,`name`,`number`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.user_contacts: ~0 rows (approximately) +/*!40000 ALTER TABLE `user_contacts` DISABLE KEYS */; +/*!40000 ALTER TABLE `user_contacts` ENABLE KEYS */; + +-- Dumping structure for table es_extended.user_licenses +CREATE TABLE IF NOT EXISTS `user_licenses` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `type` varchar(60) NOT NULL, + `owner` varchar(60) NOT NULL, + PRIMARY KEY (`id`), + KEY `owner` (`owner`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.user_licenses: ~0 rows (approximately) +/*!40000 ALTER TABLE `user_licenses` DISABLE KEYS */; +/*!40000 ALTER TABLE `user_licenses` ENABLE KEYS */; + +-- Dumping structure for table es_extended.user_parkings +CREATE TABLE IF NOT EXISTS `user_parkings` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(60) DEFAULT NULL, + `garage` varchar(60) DEFAULT NULL, + `zone` int(11) NOT NULL, + `vehicle` longtext DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.user_parkings: ~0 rows (approximately) +/*!40000 ALTER TABLE `user_parkings` DISABLE KEYS */; +/*!40000 ALTER TABLE `user_parkings` ENABLE KEYS */; + +-- Dumping structure for table es_extended.vehicles +CREATE TABLE IF NOT EXISTS `vehicles` ( + `name` varchar(60) NOT NULL, + `model` varchar(60) NOT NULL, + `price` int(11) NOT NULL, + `category` varchar(60) DEFAULT NULL, + PRIMARY KEY (`model`), + KEY `category` (`category`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.vehicles: ~240 rows (approximately) +/*!40000 ALTER TABLE `vehicles` DISABLE KEYS */; +INSERT INTO `vehicles` (`name`, `model`, `price`, `category`) VALUES + ('Adder', 'adder', 900000, 'super'), + ('Akuma', 'AKUMA', 7500, 'motorcycles'), + ('Alpha', 'alpha', 60000, 'sports'), + ('Ardent', 'ardent', 1150000, 'sportsclassics'), + ('Asea', 'asea', 5500, 'sedans'), + ('Autarch', 'autarch', 1955000, 'super'), + ('Avarus', 'avarus', 18000, 'motorcycles'), + ('Bagger', 'bagger', 13500, 'motorcycles'), + ('Baller', 'baller2', 40000, 'suvs'), + ('Baller Sport', 'baller3', 60000, 'suvs'), + ('Banshee', 'banshee', 70000, 'sports'), + ('Banshee 900R', 'banshee2', 255000, 'super'), + ('Bati 801', 'bati', 12000, 'motorcycles'), + ('Bati 801RR', 'bati2', 19000, 'motorcycles'), + ('Bestia GTS', 'bestiagts', 55000, 'sports'), + ('BF400', 'bf400', 6500, 'motorcycles'), + ('Bf Injection', 'bfinjection', 16000, 'offroad'), + ('Bifta', 'bifta', 12000, 'offroad'), + ('Bison', 'bison', 45000, 'vans'), + ('Blade', 'blade', 15000, 'muscle'), + ('Blazer', 'blazer', 6500, 'offroad'), + ('Blazer Sport', 'blazer4', 8500, 'offroad'), + ('blazer5', 'blazer5', 1755600, 'offroad'), + ('Blista', 'blista', 8000, 'compacts'), + ('BMX (velo)', 'bmx', 160, 'motorcycles'), + ('Bobcat XL', 'bobcatxl', 32000, 'vans'), + ('Brawler', 'brawler', 45000, 'offroad'), + ('Brioso R/A', 'brioso', 18000, 'compacts'), + ('Btype', 'btype', 62000, 'sportsclassics'), + ('Btype Hotroad', 'btype2', 155000, 'sportsclassics'), + ('Btype Luxe', 'btype3', 85000, 'sportsclassics'), + ('Buccaneer', 'buccaneer', 18000, 'muscle'), + ('Buccaneer Rider', 'buccaneer2', 24000, 'muscle'), + ('Buffalo', 'buffalo', 12000, 'sports'), + ('Buffalo S', 'buffalo2', 20000, 'sports'), + ('Bullet', 'bullet', 90000, 'super'), + ('Burrito', 'burrito3', 19000, 'vans'), + ('Camper', 'camper', 42000, 'vans'), + ('Carbonizzare', 'carbonizzare', 75000, 'sports'), + ('Carbon RS', 'carbonrs', 18000, 'motorcycles'), + ('Casco', 'casco', 30000, 'sportsclassics'), + ('Cavalcade', 'cavalcade2', 55000, 'suvs'), + ('Cheetah', 'cheetah', 375000, 'super'), + ('Chimera', 'chimera', 38000, 'motorcycles'), + ('Chino', 'chino', 15000, 'muscle'), + ('Chino Luxe', 'chino2', 19000, 'muscle'), + ('Cliffhanger', 'cliffhanger', 9500, 'motorcycles'), + ('Cognoscenti Cabrio', 'cogcabrio', 55000, 'coupes'), + ('Cognoscenti', 'cognoscenti', 55000, 'sedans'), + ('Comet', 'comet2', 65000, 'sports'), + ('Comet 5', 'comet5', 1145000, 'sports'), + ('Contender', 'contender', 70000, 'suvs'), + ('Coquette', 'coquette', 65000, 'sports'), + ('Coquette Classic', 'coquette2', 40000, 'sportsclassics'), + ('Coquette BlackFin', 'coquette3', 55000, 'muscle'), + ('Cruiser (velo)', 'cruiser', 510, 'motorcycles'), + ('Cyclone', 'cyclone', 1890000, 'super'), + ('Daemon', 'daemon', 11500, 'motorcycles'), + ('Daemon High', 'daemon2', 13500, 'motorcycles'), + ('Defiler', 'defiler', 9800, 'motorcycles'), + ('Deluxo', 'deluxo', 4721500, 'sportsclassics'), + ('Dominator', 'dominator', 35000, 'muscle'), + ('Double T', 'double', 28000, 'motorcycles'), + ('Dubsta', 'dubsta', 45000, 'suvs'), + ('Dubsta Luxuary', 'dubsta2', 60000, 'suvs'), + ('Bubsta 6x6', 'dubsta3', 120000, 'offroad'), + ('Dukes', 'dukes', 28000, 'muscle'), + ('Dune Buggy', 'dune', 8000, 'offroad'), + ('Elegy', 'elegy2', 38500, 'sports'), + ('Emperor', 'emperor', 8500, 'sedans'), + ('Enduro', 'enduro', 5500, 'motorcycles'), + ('Entity XF', 'entityxf', 425000, 'super'), + ('Esskey', 'esskey', 4200, 'motorcycles'), + ('Exemplar', 'exemplar', 32000, 'coupes'), + ('F620', 'f620', 40000, 'coupes'), + ('Faction', 'faction', 20000, 'muscle'), + ('Faction Rider', 'faction2', 30000, 'muscle'), + ('Faction XL', 'faction3', 40000, 'muscle'), + ('Faggio', 'faggio', 1900, 'motorcycles'), + ('Vespa', 'faggio2', 2800, 'motorcycles'), + ('Felon', 'felon', 42000, 'coupes'), + ('Felon GT', 'felon2', 55000, 'coupes'), + ('Feltzer', 'feltzer2', 55000, 'sports'), + ('Stirling GT', 'feltzer3', 65000, 'sportsclassics'), + ('Fixter (velo)', 'fixter', 225, 'motorcycles'), + ('FMJ', 'fmj', 185000, 'super'), + ('Fhantom', 'fq2', 17000, 'suvs'), + ('Fugitive', 'fugitive', 12000, 'sedans'), + ('Furore GT', 'furoregt', 45000, 'sports'), + ('Fusilade', 'fusilade', 40000, 'sports'), + ('Gargoyle', 'gargoyle', 16500, 'motorcycles'), + ('Gauntlet', 'gauntlet', 30000, 'muscle'), + ('Gang Burrito', 'gburrito', 45000, 'vans'), + ('Burrito', 'gburrito2', 29000, 'vans'), + ('Glendale', 'glendale', 6500, 'sedans'), + ('Grabger', 'granger', 50000, 'suvs'), + ('Gresley', 'gresley', 47500, 'suvs'), + ('GT 500', 'gt500', 785000, 'sportsclassics'), + ('Guardian', 'guardian', 45000, 'offroad'), + ('Hakuchou', 'hakuchou', 31000, 'motorcycles'), + ('Hakuchou Sport', 'hakuchou2', 55000, 'motorcycles'), + ('Hermes', 'hermes', 535000, 'muscle'), + ('Hexer', 'hexer', 12000, 'motorcycles'), + ('Hotknife', 'hotknife', 125000, 'muscle'), + ('Huntley S', 'huntley', 40000, 'suvs'), + ('Hustler', 'hustler', 625000, 'muscle'), + ('Infernus', 'infernus', 180000, 'super'), + ('Innovation', 'innovation', 23500, 'motorcycles'), + ('Intruder', 'intruder', 7500, 'sedans'), + ('Issi', 'issi2', 10000, 'compacts'), + ('Jackal', 'jackal', 38000, 'coupes'), + ('Jester', 'jester', 65000, 'sports'), + ('Jester(Racecar)', 'jester2', 135000, 'sports'), + ('Journey', 'journey', 6500, 'vans'), + ('Kamacho', 'kamacho', 345000, 'offroad'), + ('Khamelion', 'khamelion', 38000, 'sports'), + ('Kuruma', 'kuruma', 30000, 'sports'), + ('Landstalker', 'landstalker', 35000, 'suvs'), + ('RE-7B', 'le7b', 325000, 'super'), + ('Lynx', 'lynx', 40000, 'sports'), + ('Mamba', 'mamba', 70000, 'sports'), + ('Manana', 'manana', 12800, 'sportsclassics'), + ('Manchez', 'manchez', 5300, 'motorcycles'), + ('Massacro', 'massacro', 65000, 'sports'), + ('Massacro(Racecar)', 'massacro2', 130000, 'sports'), + ('Mesa', 'mesa', 16000, 'suvs'), + ('Mesa Trail', 'mesa3', 40000, 'suvs'), + ('Minivan', 'minivan', 13000, 'vans'), + ('Monroe', 'monroe', 55000, 'sportsclassics'), + ('The Liberator', 'monster', 210000, 'offroad'), + ('Moonbeam', 'moonbeam', 18000, 'vans'), + ('Moonbeam Rider', 'moonbeam2', 35000, 'vans'), + ('Nemesis', 'nemesis', 5800, 'motorcycles'), + ('Neon', 'neon', 1500000, 'sports'), + ('Nightblade', 'nightblade', 35000, 'motorcycles'), + ('Nightshade', 'nightshade', 65000, 'muscle'), + ('9F', 'ninef', 65000, 'sports'), + ('9F Cabrio', 'ninef2', 80000, 'sports'), + ('Omnis', 'omnis', 35000, 'sports'), + ('Oppressor', 'oppressor', 3524500, 'super'), + ('Oracle XS', 'oracle2', 35000, 'coupes'), + ('Osiris', 'osiris', 160000, 'super'), + ('Panto', 'panto', 10000, 'compacts'), + ('Paradise', 'paradise', 19000, 'vans'), + ('Pariah', 'pariah', 1420000, 'sports'), + ('Patriot', 'patriot', 55000, 'suvs'), + ('PCJ-600', 'pcj', 6200, 'motorcycles'), + ('Penumbra', 'penumbra', 28000, 'sports'), + ('Pfister', 'pfister811', 85000, 'super'), + ('Phoenix', 'phoenix', 12500, 'muscle'), + ('Picador', 'picador', 18000, 'muscle'), + ('Pigalle', 'pigalle', 20000, 'sportsclassics'), + ('Prairie', 'prairie', 12000, 'compacts'), + ('Premier', 'premier', 8000, 'sedans'), + ('Primo Custom', 'primo2', 14000, 'sedans'), + ('X80 Proto', 'prototipo', 2500000, 'super'), + ('Radius', 'radi', 29000, 'suvs'), + ('raiden', 'raiden', 1375000, 'sports'), + ('Rapid GT', 'rapidgt', 35000, 'sports'), + ('Rapid GT Convertible', 'rapidgt2', 45000, 'sports'), + ('Rapid GT3', 'rapidgt3', 885000, 'sportsclassics'), + ('Reaper', 'reaper', 150000, 'super'), + ('Rebel', 'rebel2', 35000, 'offroad'), + ('Regina', 'regina', 5000, 'sedans'), + ('Retinue', 'retinue', 615000, 'sportsclassics'), + ('Revolter', 'revolter', 1610000, 'sports'), + ('riata', 'riata', 380000, 'offroad'), + ('Rocoto', 'rocoto', 45000, 'suvs'), + ('Ruffian', 'ruffian', 6800, 'motorcycles'), + ('Ruiner 2', 'ruiner2', 5745600, 'muscle'), + ('Rumpo', 'rumpo', 15000, 'vans'), + ('Rumpo Trail', 'rumpo3', 19500, 'vans'), + ('Sabre Turbo', 'sabregt', 20000, 'muscle'), + ('Sabre GT', 'sabregt2', 25000, 'muscle'), + ('Sanchez', 'sanchez', 5300, 'motorcycles'), + ('Sanchez Sport', 'sanchez2', 5300, 'motorcycles'), + ('Sanctus', 'sanctus', 25000, 'motorcycles'), + ('Sandking', 'sandking', 55000, 'offroad'), + ('Savestra', 'savestra', 990000, 'sportsclassics'), + ('SC 1', 'sc1', 1603000, 'super'), + ('Schafter', 'schafter2', 25000, 'sedans'), + ('Schafter V12', 'schafter3', 50000, 'sports'), + ('Scorcher (velo)', 'scorcher', 280, 'motorcycles'), + ('Seminole', 'seminole', 25000, 'suvs'), + ('Sentinel', 'sentinel', 32000, 'coupes'), + ('Sentinel XS', 'sentinel2', 40000, 'coupes'), + ('Sentinel3', 'sentinel3', 650000, 'sports'), + ('Seven 70', 'seven70', 39500, 'sports'), + ('ETR1', 'sheava', 220000, 'super'), + ('Shotaro Concept', 'shotaro', 320000, 'motorcycles'), + ('Slam Van', 'slamvan3', 11500, 'muscle'), + ('Sovereign', 'sovereign', 22000, 'motorcycles'), + ('Stinger', 'stinger', 80000, 'sportsclassics'), + ('Stinger GT', 'stingergt', 75000, 'sportsclassics'), + ('Streiter', 'streiter', 500000, 'sports'), + ('Stretch', 'stretch', 90000, 'sedans'), + ('Stromberg', 'stromberg', 3185350, 'sports'), + ('Sultan', 'sultan', 15000, 'sports'), + ('Sultan RS', 'sultanrs', 65000, 'super'), + ('Super Diamond', 'superd', 130000, 'sedans'), + ('Surano', 'surano', 50000, 'sports'), + ('Surfer', 'surfer', 12000, 'vans'), + ('T20', 't20', 300000, 'super'), + ('Tailgater', 'tailgater', 30000, 'sedans'), + ('Tampa', 'tampa', 16000, 'muscle'), + ('Drift Tampa', 'tampa2', 80000, 'sports'), + ('Thrust', 'thrust', 24000, 'motorcycles'), + ('Tri bike (velo)', 'tribike3', 520, 'motorcycles'), + ('Trophy Truck', 'trophytruck', 60000, 'offroad'), + ('Trophy Truck Limited', 'trophytruck2', 80000, 'offroad'), + ('Tropos', 'tropos', 40000, 'sports'), + ('Turismo R', 'turismor', 350000, 'super'), + ('Tyrus', 'tyrus', 600000, 'super'), + ('Vacca', 'vacca', 120000, 'super'), + ('Vader', 'vader', 7200, 'motorcycles'), + ('Verlierer', 'verlierer2', 70000, 'sports'), + ('Vigero', 'vigero', 12500, 'muscle'), + ('Virgo', 'virgo', 14000, 'muscle'), + ('Viseris', 'viseris', 875000, 'sportsclassics'), + ('Visione', 'visione', 2250000, 'super'), + ('Voltic', 'voltic', 90000, 'super'), + ('Voltic 2', 'voltic2', 3830400, 'super'), + ('Voodoo', 'voodoo', 7200, 'muscle'), + ('Vortex', 'vortex', 9800, 'motorcycles'), + ('Warrener', 'warrener', 4000, 'sedans'), + ('Washington', 'washington', 9000, 'sedans'), + ('Windsor', 'windsor', 95000, 'coupes'), + ('Windsor Drop', 'windsor2', 125000, 'coupes'), + ('Woflsbane', 'wolfsbane', 9000, 'motorcycles'), + ('XLS', 'xls', 32000, 'suvs'), + ('Yosemite', 'yosemite', 485000, 'muscle'), + ('Youga', 'youga', 10800, 'vans'), + ('Youga Luxuary', 'youga2', 14500, 'vans'), + ('Z190', 'z190', 900000, 'sportsclassics'), + ('Zentorno', 'zentorno', 1500000, 'super'), + ('Zion', 'zion', 36000, 'coupes'), + ('Zion Cabrio', 'zion2', 45000, 'coupes'), + ('Zombie', 'zombiea', 9500, 'motorcycles'), + ('Zombie Luxuary', 'zombieb', 12000, 'motorcycles'), + ('Z-Type', 'ztype', 220000, 'sportsclassics'); +/*!40000 ALTER TABLE `vehicles` ENABLE KEYS */; + +-- Dumping structure for table es_extended.vehicle_categories +CREATE TABLE IF NOT EXISTS `vehicle_categories` ( + `name` varchar(60) NOT NULL, + `label` varchar(60) NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.vehicle_categories: ~11 rows (approximately) +/*!40000 ALTER TABLE `vehicle_categories` DISABLE KEYS */; +INSERT INTO `vehicle_categories` (`name`, `label`) VALUES + ('compacts', 'Compacts'), + ('coupes', 'Coupés'), + ('motorcycles', 'Motos'), + ('muscle', 'Muscle'), + ('offroad', 'Off Road'), + ('sedans', 'Sedans'), + ('sports', 'Sports'), + ('sportsclassics', 'Sports Classics'), + ('super', 'Super'), + ('suvs', 'SUVs'), + ('vans', 'Vans'); +/*!40000 ALTER TABLE `vehicle_categories` ENABLE KEYS */; + +-- Dumping structure for table es_extended.vehicle_sold +CREATE TABLE IF NOT EXISTS `vehicle_sold` ( + `client` varchar(50) NOT NULL, + `model` varchar(50) NOT NULL, + `plate` varchar(50) NOT NULL, + `soldby` varchar(50) NOT NULL, + `date` varchar(50) NOT NULL, + PRIMARY KEY (`plate`) +) ENGINE=InnoDB; + +-- Dumping data for table es_extended.vehicle_sold: ~0 rows (approximately) +/*!40000 ALTER TABLE `vehicle_sold` DISABLE KEYS */; +/*!40000 ALTER TABLE `vehicle_sold` ENABLE KEYS */; + +-- Dumping structure for table es_extended.weashops +CREATE TABLE IF NOT EXISTS `weashops` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `zone` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=41; + +-- Dumping data for table es_extended.weashops: ~40 rows (approximately) +/*!40000 ALTER TABLE `weashops` DISABLE KEYS */; +INSERT INTO `weashops` (`id`, `zone`, `item`, `price`) VALUES + (1, 'GunShop', 'WEAPON_PISTOL', 300), + (2, 'BlackWeashop', 'WEAPON_PISTOL', 500), + (3, 'GunShop', 'WEAPON_FLASHLIGHT', 60), + (4, 'BlackWeashop', 'WEAPON_FLASHLIGHT', 70), + (5, 'GunShop', 'WEAPON_MACHETE', 90), + (6, 'BlackWeashop', 'WEAPON_MACHETE', 110), + (7, 'GunShop', 'WEAPON_NIGHTSTICK', 150), + (8, 'BlackWeashop', 'WEAPON_NIGHTSTICK', 150), + (9, 'GunShop', 'WEAPON_BAT', 100), + (10, 'BlackWeashop', 'WEAPON_BAT', 100), + (11, 'GunShop', 'WEAPON_STUNGUN', 50), + (12, 'BlackWeashop', 'WEAPON_STUNGUN', 50), + (13, 'GunShop', 'WEAPON_MICROSMG', 1400), + (14, 'BlackWeashop', 'WEAPON_MICROSMG', 1700), + (15, 'GunShop', 'WEAPON_PUMPSHOTGUN', 3400), + (16, 'BlackWeashop', 'WEAPON_PUMPSHOTGUN', 3500), + (17, 'GunShop', 'WEAPON_ASSAULTRIFLE', 10000), + (18, 'BlackWeashop', 'WEAPON_ASSAULTRIFLE', 11000), + (19, 'GunShop', 'WEAPON_SPECIALCARBINE', 15000), + (20, 'BlackWeashop', 'WEAPON_SPECIALCARBINE', 16500), + (21, 'GunShop', 'WEAPON_SNIPERRIFLE', 22000), + (22, 'BlackWeashop', 'WEAPON_SNIPERRIFLE', 24000), + (23, 'GunShop', 'WEAPON_FIREWORK', 18000), + (24, 'BlackWeashop', 'WEAPON_FIREWORK', 20000), + (25, 'GunShop', 'WEAPON_GRENADE', 500), + (26, 'BlackWeashop', 'WEAPON_GRENADE', 650), + (27, 'GunShop', 'WEAPON_BZGAS', 200), + (28, 'BlackWeashop', 'WEAPON_BZGAS', 350), + (29, 'GunShop', 'WEAPON_FIREEXTINGUISHER', 100), + (30, 'BlackWeashop', 'WEAPON_FIREEXTINGUISHER', 100), + (31, 'GunShop', 'WEAPON_BALL', 50), + (32, 'BlackWeashop', 'WEAPON_BALL', 50), + (33, 'GunShop', 'WEAPON_SMOKEGRENADE', 100), + (34, 'BlackWeashop', 'WEAPON_SMOKEGRENADE', 100), + (35, 'BlackWeashop', 'WEAPON_APPISTOL', 1100), + (36, 'BlackWeashop', 'WEAPON_CARBINERIFLE', 12000), + (37, 'BlackWeashop', 'WEAPON_HEAVYSNIPER', 30000), + (38, 'BlackWeashop', 'WEAPON_MINIGUN', 45000), + (39, 'BlackWeashop', 'WEAPON_RAILGUN', 50000), + (40, 'BlackWeashop', 'WEAPON_STICKYBOMB', 500); +/*!40000 ALTER TABLE `weashops` ENABLE KEYS */; + +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;